Merge ref 'f889772d65' from rust-lang/rust

Pull recent changes from https://github.com/rust-lang/rust via Josh.

Upstream ref: rust-lang/rust@f889772d65
Filtered ref: rust-lang/miri@1fa28eb9ac
Upstream diff: 9f4b56a5ae...f889772d65

This merge was created using https://github.com/rust-lang/josh-sync.
This commit is contained in:
The Miri Cronjob Bot 2026-02-06 05:23:58 +00:00
commit 13ebd31ecd
270 changed files with 5612 additions and 7965 deletions

View file

@ -3490,7 +3490,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
@ -3515,7 +3514,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_macros",
"rustc_session",
"rustc_span",
@ -3601,7 +3599,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_lexer",
@ -3672,7 +3669,6 @@ dependencies = [
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_fs_util",
"rustc_hashes",
"rustc_hir",
@ -3774,11 +3770,8 @@ dependencies = [
"libc",
"rustc_abi",
"rustc_ast",
"rustc_ast_lowering",
"rustc_ast_passes",
"rustc_ast_pretty",
"rustc_borrowck",
"rustc_builtin_macros",
"rustc_codegen_ssa",
"rustc_const_eval",
"rustc_data_structures",
@ -3787,7 +3780,6 @@ dependencies = [
"rustc_feature",
"rustc_hir_analysis",
"rustc_hir_pretty",
"rustc_hir_typeck",
"rustc_index",
"rustc_interface",
"rustc_lexer",
@ -3800,7 +3792,6 @@ dependencies = [
"rustc_mir_transform",
"rustc_parse",
"rustc_passes",
"rustc_pattern_analysis",
"rustc_public",
"rustc_resolve",
"rustc_session",
@ -3850,7 +3841,6 @@ dependencies = [
"rustc_data_structures",
"rustc_error_codes",
"rustc_error_messages",
"rustc_fluent_macro",
"rustc_hashes",
"rustc_index",
"rustc_lint_defs",
@ -3875,7 +3865,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_lexer",
"rustc_lint_defs",
@ -4017,7 +4006,6 @@ dependencies = [
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_hir_analysis",
"rustc_hir_pretty",
@ -4039,7 +4027,6 @@ name = "rustc_incremental"
version = "0.0.0"
dependencies = [
"rand 0.9.2",
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
"rustc_fs_util",
@ -4051,7 +4038,6 @@ dependencies = [
"rustc_serialize",
"rustc_session",
"rustc_span",
"thin-vec",
"tracing",
]
@ -4237,7 +4223,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_fluent_macro",
"rustc_fs_util",
"rustc_hir",
"rustc_hir_pretty",
@ -4271,7 +4256,6 @@ dependencies = [
"rustc_error_messages",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_graphviz",
"rustc_hashes",
"rustc_hir",
@ -4347,7 +4331,6 @@ dependencies = [
"rustc_const_eval",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_infer",
@ -4461,7 +4444,6 @@ dependencies = [
"rustc_arena",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",
@ -4534,9 +4516,11 @@ version = "0.0.0"
dependencies = [
"measureme",
"rustc_data_structures",
"rustc_errors",
"rustc_hashes",
"rustc_hir",
"rustc_index",
"rustc_macros",
"rustc_middle",
"rustc_query_system",
"rustc_serialize",
@ -4581,7 +4565,6 @@ dependencies = [
"rustc_errors",
"rustc_expand",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_macros",

View file

@ -3,6 +3,8 @@
// Several crates are depended upon but unused so that they are present in the sysroot
#![expect(unused_crate_dependencies)]
use std::process::ExitCode;
// A note about jemalloc: rustc uses jemalloc when built for CI and
// distribution. The obvious way to do this is with the `#[global_allocator]`
// mechanism. However, for complicated reasons (see
@ -38,6 +40,6 @@
#[cfg(feature = "jemalloc")]
use tikv_jemalloc_sys as _;
fn main() {
fn main() -> ExitCode {
rustc_driver::main()
}

View file

@ -15,7 +15,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_macros = { path = "../rustc_macros" }

View file

@ -1,191 +0,0 @@
ast_lowering_abi_specified_multiple_times =
`{$prev_name}` ABI specified multiple times
.label = previously specified here
.note = these ABIs are equivalent on the current target
ast_lowering_arbitrary_expression_in_pattern =
arbitrary expressions aren't allowed in patterns
.pattern_from_macro_note = the `expr` fragment specifier forces the metavariable's content to be an expression
.const_block_in_pattern_help = use a named `const`-item or an `if`-guard (`x if x == const {"{ ... }"}`) instead
ast_lowering_argument = argument
ast_lowering_assoc_ty_binding_in_dyn =
associated type bounds are not allowed in `dyn` types
.suggestion = use `impl Trait` to introduce a type instead
ast_lowering_assoc_ty_parentheses =
parenthesized generic arguments cannot be used in associated type constraints
ast_lowering_async_bound_not_on_trait =
`async` bound modifier only allowed on trait, not `{$descr}`
ast_lowering_async_bound_only_for_fn_traits =
`async` bound modifier only allowed on `Fn`/`FnMut`/`FnOnce` traits
ast_lowering_async_coroutines_not_supported =
`async` coroutines are not yet supported
ast_lowering_att_syntax_only_x86 =
the `att_syntax` option is only supported on x86
ast_lowering_await_only_in_async_fn_and_blocks =
`await` is only allowed inside `async` functions and blocks
.label = only allowed inside `async` functions and blocks
ast_lowering_bad_return_type_notation_inputs =
argument types not allowed with return type notation
.suggestion = remove the input types
ast_lowering_bad_return_type_notation_needs_dots = return type notation arguments must be elided with `..`
.suggestion = use the correct syntax by adding `..` to the arguments
ast_lowering_bad_return_type_notation_output =
return type not allowed with return type notation
ast_lowering_bad_return_type_notation_output_suggestion = use the right argument notation and remove the return type
ast_lowering_bad_return_type_notation_position = return type notation not allowed in this position yet
ast_lowering_clobber_abi_not_supported =
`clobber_abi` is not supported on this target
ast_lowering_closure_cannot_be_static = closures cannot be static
ast_lowering_coroutine_too_many_parameters =
too many parameters for a coroutine (expected 0 or 1 parameters)
ast_lowering_default_field_in_tuple = default fields are not supported in tuple structs
.label = default fields are only supported on structs
ast_lowering_delegation_cycle_in_signature_resolution = encountered a cycle during delegation signature resolution
ast_lowering_delegation_unresolved_callee = failed to resolve delegation callee
ast_lowering_does_not_support_modifiers =
the `{$class_name}` register class does not support template modifiers
ast_lowering_extra_double_dot =
`..` can only be used once per {$ctx} pattern
.label = can only be used once per {$ctx} pattern
ast_lowering_functional_record_update_destructuring_assignment =
functional record updates are not allowed in destructuring assignments
.suggestion = consider removing the trailing pattern
ast_lowering_generic_param_default_in_binder =
defaults for generic parameters are not allowed in `for<...>` binders
ast_lowering_generic_type_with_parentheses =
parenthesized type parameters may only be used with a `Fn` trait
.label = only `Fn` traits may use parentheses
ast_lowering_inclusive_range_with_no_end = inclusive range with no end
ast_lowering_inline_asm_unsupported_target =
inline assembly is unsupported on this target
ast_lowering_invalid_abi =
invalid ABI: found `{$abi}`
.label = invalid ABI
.note = invoke `{$command}` for a full list of supported calling conventions
ast_lowering_invalid_abi_clobber_abi =
invalid ABI for `clobber_abi`
.note = the following ABIs are supported on this target: {$supported_abis}
ast_lowering_invalid_abi_suggestion = there's a similarly named valid ABI `{$suggestion}`
ast_lowering_invalid_asm_template_modifier_const =
asm template modifiers are not allowed for `const` arguments
ast_lowering_invalid_asm_template_modifier_label =
asm template modifiers are not allowed for `label` arguments
ast_lowering_invalid_asm_template_modifier_reg_class =
invalid asm template modifier for this register class
ast_lowering_invalid_asm_template_modifier_sym =
asm template modifiers are not allowed for `sym` arguments
ast_lowering_invalid_legacy_const_generic_arg =
invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items
ast_lowering_invalid_legacy_const_generic_arg_suggestion =
try using a const generic argument instead
ast_lowering_invalid_register =
invalid register `{$reg}`: {$error}
ast_lowering_invalid_register_class =
invalid register class `{$reg_class}`: unknown register class
.note = the following register classes are supported on this target: {$supported_register_classes}
ast_lowering_match_arm_with_no_body =
`match` arm with no body
.suggestion = add a body after the pattern
ast_lowering_misplaced_double_dot =
`..` patterns are not allowed here
.note = only allowed in tuple, tuple struct, and slice patterns
ast_lowering_misplaced_impl_trait =
`impl Trait` is not allowed in {$position}
.note = `impl Trait` is only allowed in arguments and return types of functions and methods
ast_lowering_never_pattern_with_body =
a never pattern is always unreachable
.label = this will never be executed
.suggestion = remove this expression
ast_lowering_never_pattern_with_guard =
a guard on a never pattern will never be run
.suggestion = remove this guard
ast_lowering_no_precise_captures_on_apit = `use<...>` precise capturing syntax not allowed in argument-position `impl Trait`
ast_lowering_previously_used_here = previously used here
ast_lowering_register1 = register `{$reg1_name}`
ast_lowering_register2 = register `{$reg2_name}`
ast_lowering_register_class_only_clobber =
register class `{$reg_class_name}` can only be used as a clobber, not as an input or output
ast_lowering_register_class_only_clobber_stable =
register class `{$reg_class_name}` can only be used as a clobber in stable
ast_lowering_register_conflict =
register `{$reg1_name}` conflicts with register `{$reg2_name}`
.help = use `lateout` instead of `out` to avoid conflict
ast_lowering_remove_parentheses = remove these parentheses
ast_lowering_sub_tuple_binding =
`{$ident_name} @` is not allowed in a {$ctx}
.label = this is only allowed in slice patterns
.help = remove this and bind each tuple field independently
ast_lowering_sub_tuple_binding_suggestion = if you don't need to use the contents of {$ident}, discard the tuple's remaining fields
ast_lowering_support_modifiers =
the `{$class_name}` register class supports the following template modifiers: {$modifiers}
ast_lowering_template_modifier = template modifier
ast_lowering_this_not_async = this is not `async`
ast_lowering_underscore_expr_lhs_assign =
in expressions, `_` can only be used on the left-hand side of an assignment
.label = `_` not allowed here
ast_lowering_union_default_field_values = unions cannot have default field values
ast_lowering_unstable_inline_assembly = inline assembly is not stable yet on this architecture
ast_lowering_unstable_inline_assembly_label_operand_with_outputs =
using both label and output operands for inline assembly is unstable
ast_lowering_unstable_may_unwind = the `may_unwind` option is unstable
ast_lowering_use_angle_brackets = use angle brackets instead
ast_lowering_yield = yield syntax is experimental
ast_lowering_yield_in_closure =
`yield` can only be used in `#[coroutine]` closures, or `gen` blocks
.suggestion = use `#[coroutine]` to make this closure a coroutine

View file

@ -3,6 +3,7 @@ use std::fmt::Write;
use rustc_ast::*;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_errors::inline_fluent;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_session::parse::feature_err;
@ -19,8 +20,7 @@ use super::errors::{
RegisterConflict,
};
use crate::{
AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode,
ResolverAstLoweringExt, fluent_generated as fluent,
AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt,
};
impl<'a, 'hir> LoweringContext<'a, 'hir> {
@ -67,7 +67,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&self.tcx.sess,
sym::asm_experimental_arch,
sp,
fluent::ast_lowering_unstable_inline_assembly,
inline_fluent!("inline assembly is not stable yet on this architecture"),
)
.emit();
}
@ -84,7 +84,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
&self.tcx.sess,
sym::asm_unwind,
sp,
fluent::ast_lowering_unstable_may_unwind,
inline_fluent!("the `may_unwind` option is unstable"),
)
.emit();
}
@ -499,7 +499,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
sess,
sym::asm_goto_with_outputs,
*op_sp,
fluent::ast_lowering_unstable_inline_assembly_label_operand_with_outputs,
inline_fluent!(
"using both label and output operands for inline assembly is unstable"
),
)
.emit();
}

View file

@ -4,17 +4,17 @@ use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Ident, Span, Symbol};
#[derive(Diagnostic)]
#[diag(ast_lowering_generic_type_with_parentheses, code = E0214)]
#[diag("parenthesized type parameters may only be used with a `Fn` trait", code = E0214)]
pub(crate) struct GenericTypeWithParentheses {
#[primary_span]
#[label]
#[label("only `Fn` traits may use parentheses")]
pub span: Span,
#[subdiagnostic]
pub sub: Option<UseAngleBrackets>,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(ast_lowering_use_angle_brackets, applicability = "maybe-incorrect")]
#[multipart_suggestion("use angle brackets instead", applicability = "maybe-incorrect")]
pub(crate) struct UseAngleBrackets {
#[suggestion_part(code = "<")]
pub open_param: Span,
@ -23,11 +23,11 @@ pub(crate) struct UseAngleBrackets {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_abi, code = E0703)]
#[note]
#[diag("invalid ABI: found `{$abi}`", code = E0703)]
#[note("invoke `{$command}` for a full list of supported calling conventions")]
pub(crate) struct InvalidAbi {
#[primary_span]
#[label]
#[label("invalid ABI")]
pub span: Span,
pub abi: Symbol,
pub command: String,
@ -36,16 +36,16 @@ pub(crate) struct InvalidAbi {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_default_field_in_tuple)]
#[diag("default fields are not supported in tuple structs")]
pub(crate) struct TupleStructWithDefault {
#[primary_span]
#[label]
#[label("default fields are only supported on structs")]
pub span: Span,
}
#[derive(Subdiagnostic)]
#[suggestion(
ast_lowering_invalid_abi_suggestion,
"there's a similarly named valid ABI `{$suggestion}`",
code = "\"{suggestion}\"",
applicability = "maybe-incorrect",
style = "verbose"
@ -57,7 +57,7 @@ pub(crate) struct InvalidAbiSuggestion {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_assoc_ty_parentheses)]
#[diag("parenthesized generic arguments cannot be used in associated type constraints")]
pub(crate) struct AssocTyParentheses {
#[primary_span]
pub span: Span,
@ -67,12 +67,12 @@ pub(crate) struct AssocTyParentheses {
#[derive(Subdiagnostic)]
pub(crate) enum AssocTyParenthesesSub {
#[multipart_suggestion(ast_lowering_remove_parentheses)]
#[multipart_suggestion("remove these parentheses")]
Empty {
#[suggestion_part(code = "")]
parentheses_span: Span,
},
#[multipart_suggestion(ast_lowering_use_angle_brackets)]
#[multipart_suggestion("use angle brackets instead")]
NotEmpty {
#[suggestion_part(code = "<")]
open_param: Span,
@ -82,8 +82,8 @@ pub(crate) enum AssocTyParenthesesSub {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_misplaced_impl_trait, code = E0562)]
#[note]
#[diag("`impl Trait` is not allowed in {$position}", code = E0562)]
#[note("`impl Trait` is only allowed in arguments and return types of functions and methods")]
pub(crate) struct MisplacedImplTrait<'a> {
#[primary_span]
pub span: Span,
@ -91,97 +91,106 @@ pub(crate) struct MisplacedImplTrait<'a> {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_assoc_ty_binding_in_dyn)]
#[diag("associated type bounds are not allowed in `dyn` types")]
pub(crate) struct MisplacedAssocTyBinding {
#[primary_span]
pub span: Span,
#[suggestion(code = " = impl", applicability = "maybe-incorrect", style = "verbose")]
#[suggestion(
"use `impl Trait` to introduce a type instead",
code = " = impl",
applicability = "maybe-incorrect",
style = "verbose"
)]
pub suggestion: Option<Span>,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_underscore_expr_lhs_assign)]
#[diag("in expressions, `_` can only be used on the left-hand side of an assignment")]
pub(crate) struct UnderscoreExprLhsAssign {
#[primary_span]
#[label]
#[label("`_` not allowed here")]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_await_only_in_async_fn_and_blocks, code = E0728)]
#[diag("`await` is only allowed inside `async` functions and blocks", code = E0728)]
pub(crate) struct AwaitOnlyInAsyncFnAndBlocks {
#[primary_span]
#[label]
#[label("only allowed inside `async` functions and blocks")]
pub await_kw_span: Span,
#[label(ast_lowering_this_not_async)]
#[label("this is not `async`")]
pub item_span: Option<Span>,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_coroutine_too_many_parameters, code = E0628)]
#[diag("too many parameters for a coroutine (expected 0 or 1 parameters)", code = E0628)]
pub(crate) struct CoroutineTooManyParameters {
#[primary_span]
pub fn_decl_span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_closure_cannot_be_static, code = E0697)]
#[diag("closures cannot be static", code = E0697)]
pub(crate) struct ClosureCannotBeStatic {
#[primary_span]
pub fn_decl_span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_functional_record_update_destructuring_assignment)]
#[diag("functional record updates are not allowed in destructuring assignments")]
pub(crate) struct FunctionalRecordUpdateDestructuringAssignment {
#[primary_span]
#[suggestion(code = "", applicability = "machine-applicable")]
#[suggestion(
"consider removing the trailing pattern",
code = "",
applicability = "machine-applicable"
)]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_async_coroutines_not_supported, code = E0727)]
#[diag("`async` coroutines are not yet supported", code = E0727)]
pub(crate) struct AsyncCoroutinesNotSupported {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_inline_asm_unsupported_target, code = E0472)]
#[diag("inline assembly is unsupported on this target", code = E0472)]
pub(crate) struct InlineAsmUnsupportedTarget {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_att_syntax_only_x86)]
#[diag("the `att_syntax` option is only supported on x86")]
pub(crate) struct AttSyntaxOnlyX86 {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_abi_specified_multiple_times)]
#[diag("`{$prev_name}` ABI specified multiple times")]
pub(crate) struct AbiSpecifiedMultipleTimes {
#[primary_span]
pub abi_span: Span,
pub prev_name: Symbol,
#[label]
#[label("previously specified here")]
pub prev_span: Span,
#[note]
#[note("these ABIs are equivalent on the current target")]
pub equivalent: bool,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_clobber_abi_not_supported)]
#[diag("`clobber_abi` is not supported on this target")]
pub(crate) struct ClobberAbiNotSupported {
#[primary_span]
pub abi_span: Span,
}
#[derive(Diagnostic)]
#[note]
#[diag(ast_lowering_invalid_abi_clobber_abi)]
#[note("the following ABIs are supported on this target: {$supported_abis}")]
#[diag("invalid ABI for `clobber_abi`")]
pub(crate) struct InvalidAbiClobberAbi {
#[primary_span]
pub abi_span: Span,
@ -189,7 +198,7 @@ pub(crate) struct InvalidAbiClobberAbi {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_register)]
#[diag("invalid register `{$reg}`: {$error}")]
pub(crate) struct InvalidRegister<'a> {
#[primary_span]
pub op_span: Span,
@ -198,8 +207,10 @@ pub(crate) struct InvalidRegister<'a> {
}
#[derive(Diagnostic)]
#[note]
#[diag(ast_lowering_invalid_register_class)]
#[note(
"the following register classes are supported on this target: {$supported_register_classes}"
)]
#[diag("invalid register class `{$reg_class}`: unknown register class")]
pub(crate) struct InvalidRegisterClass {
#[primary_span]
pub op_span: Span,
@ -208,12 +219,12 @@ pub(crate) struct InvalidRegisterClass {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_asm_template_modifier_reg_class)]
#[diag("invalid asm template modifier for this register class")]
pub(crate) struct InvalidAsmTemplateModifierRegClass {
#[primary_span]
#[label(ast_lowering_template_modifier)]
#[label("template modifier")]
pub placeholder_span: Span,
#[label(ast_lowering_argument)]
#[label("argument")]
pub op_span: Span,
#[subdiagnostic]
pub sub: InvalidAsmTemplateModifierRegClassSub,
@ -221,44 +232,48 @@ pub(crate) struct InvalidAsmTemplateModifierRegClass {
#[derive(Subdiagnostic)]
pub(crate) enum InvalidAsmTemplateModifierRegClassSub {
#[note(ast_lowering_support_modifiers)]
#[note(
"the `{$class_name}` register class supports the following template modifiers: {$modifiers}"
)]
SupportModifier { class_name: Symbol, modifiers: String },
#[note(ast_lowering_does_not_support_modifiers)]
#[note("the `{$class_name}` register class does not support template modifiers")]
DoesNotSupportModifier { class_name: Symbol },
}
#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_asm_template_modifier_const)]
#[diag("asm template modifiers are not allowed for `const` arguments")]
pub(crate) struct InvalidAsmTemplateModifierConst {
#[primary_span]
#[label(ast_lowering_template_modifier)]
#[label("template modifier")]
pub placeholder_span: Span,
#[label(ast_lowering_argument)]
#[label("argument")]
pub op_span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_asm_template_modifier_sym)]
#[diag("asm template modifiers are not allowed for `sym` arguments")]
pub(crate) struct InvalidAsmTemplateModifierSym {
#[primary_span]
#[label(ast_lowering_template_modifier)]
#[label("template modifier")]
pub placeholder_span: Span,
#[label(ast_lowering_argument)]
#[label("argument")]
pub op_span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_asm_template_modifier_label)]
#[diag("asm template modifiers are not allowed for `label` arguments")]
pub(crate) struct InvalidAsmTemplateModifierLabel {
#[primary_span]
#[label(ast_lowering_template_modifier)]
#[label("template modifier")]
pub placeholder_span: Span,
#[label(ast_lowering_argument)]
#[label("argument")]
pub op_span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_register_class_only_clobber)]
#[diag(
"register class `{$reg_class_name}` can only be used as a clobber, not as an input or output"
)]
pub(crate) struct RegisterClassOnlyClobber {
#[primary_span]
pub op_span: Span,
@ -266,7 +281,7 @@ pub(crate) struct RegisterClassOnlyClobber {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_register_class_only_clobber_stable)]
#[diag("register class `{$reg_class_name}` can only be used as a clobber in stable")]
pub(crate) struct RegisterClassOnlyClobberStable {
#[primary_span]
pub op_span: Span,
@ -274,27 +289,27 @@ pub(crate) struct RegisterClassOnlyClobberStable {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_register_conflict)]
#[diag("register `{$reg1_name}` conflicts with register `{$reg2_name}`")]
pub(crate) struct RegisterConflict<'a> {
#[primary_span]
#[label(ast_lowering_register1)]
#[label("register `{$reg1_name}`")]
pub op_span1: Span,
#[label(ast_lowering_register2)]
#[label("register `{$reg2_name}`")]
pub op_span2: Span,
pub reg1_name: &'a str,
pub reg2_name: &'a str,
#[help]
#[help("use `lateout` instead of `out` to avoid conflict")]
pub in_out: Option<Span>,
}
#[derive(Diagnostic)]
#[help]
#[diag(ast_lowering_sub_tuple_binding)]
#[help("remove this and bind each tuple field independently")]
#[diag("`{$ident_name} @` is not allowed in a {$ctx}")]
pub(crate) struct SubTupleBinding<'a> {
#[primary_span]
#[label]
#[label("this is only allowed in slice patterns")]
#[suggestion(
ast_lowering_sub_tuple_binding_suggestion,
"if you don't need to use the contents of {$ident}, discard the tuple's remaining fields",
style = "verbose",
code = "..",
applicability = "maybe-incorrect"
@ -306,63 +321,67 @@ pub(crate) struct SubTupleBinding<'a> {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_extra_double_dot)]
#[diag("`..` can only be used once per {$ctx} pattern")]
pub(crate) struct ExtraDoubleDot<'a> {
#[primary_span]
#[label]
#[label("can only be used once per {$ctx} pattern")]
pub span: Span,
#[label(ast_lowering_previously_used_here)]
#[label("previously used here")]
pub prev_span: Span,
pub ctx: &'a str,
}
#[derive(Diagnostic)]
#[note]
#[diag(ast_lowering_misplaced_double_dot)]
#[note("only allowed in tuple, tuple struct, and slice patterns")]
#[diag("`..` patterns are not allowed here")]
pub(crate) struct MisplacedDoubleDot {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_match_arm_with_no_body)]
#[diag("`match` arm with no body")]
pub(crate) struct MatchArmWithNoBody {
#[primary_span]
pub span: Span,
#[suggestion(code = " => todo!(),", applicability = "has-placeholders")]
#[suggestion(
"add a body after the pattern",
code = " => todo!(),",
applicability = "has-placeholders"
)]
pub suggestion: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_never_pattern_with_body)]
#[diag("a never pattern is always unreachable")]
pub(crate) struct NeverPatternWithBody {
#[primary_span]
#[label]
#[suggestion(code = "", applicability = "maybe-incorrect")]
#[label("this will never be executed")]
#[suggestion("remove this expression", code = "", applicability = "maybe-incorrect")]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_never_pattern_with_guard)]
#[diag("a guard on a never pattern will never be run")]
pub(crate) struct NeverPatternWithGuard {
#[primary_span]
#[suggestion(code = "", applicability = "maybe-incorrect")]
#[suggestion("remove this guard", code = "", applicability = "maybe-incorrect")]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_arbitrary_expression_in_pattern)]
#[diag("arbitrary expressions aren't allowed in patterns")]
pub(crate) struct ArbitraryExpressionInPattern {
#[primary_span]
pub span: Span,
#[note(ast_lowering_pattern_from_macro_note)]
#[note("the `expr` fragment specifier forces the metavariable's content to be an expression")]
pub pattern_from_macro_note: bool,
#[help(ast_lowering_const_block_in_pattern_help)]
#[help("use a named `const`-item or an `if`-guard (`x if x == const {\"{ ... }\"}`) instead")]
pub const_block_in_pattern_help: bool,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_inclusive_range_with_no_end)]
#[diag("inclusive range with no end")]
pub(crate) struct InclusiveRangeWithNoEnd {
#[primary_span]
pub span: Span,
@ -370,7 +389,7 @@ pub(crate) struct InclusiveRangeWithNoEnd {
#[derive(Subdiagnostic)]
#[multipart_suggestion(
ast_lowering_bad_return_type_notation_output_suggestion,
"use the right argument notation and remove the return type",
applicability = "machine-applicable",
style = "verbose"
)]
@ -384,26 +403,36 @@ pub(crate) struct RTNSuggestion {
#[derive(Diagnostic)]
pub(crate) enum BadReturnTypeNotation {
#[diag(ast_lowering_bad_return_type_notation_inputs)]
#[diag("argument types not allowed with return type notation")]
Inputs {
#[primary_span]
#[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")]
#[suggestion(
"remove the input types",
code = "(..)",
applicability = "machine-applicable",
style = "verbose"
)]
span: Span,
},
#[diag(ast_lowering_bad_return_type_notation_output)]
#[diag("return type not allowed with return type notation")]
Output {
#[primary_span]
span: Span,
#[subdiagnostic]
suggestion: RTNSuggestion,
},
#[diag(ast_lowering_bad_return_type_notation_needs_dots)]
#[diag("return type notation arguments must be elided with `..`")]
NeedsDots {
#[primary_span]
#[suggestion(code = "(..)", applicability = "machine-applicable", style = "verbose")]
#[suggestion(
"use the correct syntax by adding `..` to the arguments",
code = "(..)",
applicability = "machine-applicable",
style = "verbose"
)]
span: Span,
},
#[diag(ast_lowering_bad_return_type_notation_position)]
#[diag("return type notation not allowed in this position yet")]
Position {
#[primary_span]
span: Span,
@ -411,14 +440,14 @@ pub(crate) enum BadReturnTypeNotation {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_generic_param_default_in_binder)]
#[diag("defaults for generic parameters are not allowed in `for<...>` binders")]
pub(crate) struct GenericParamDefaultInBinder {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_async_bound_not_on_trait)]
#[diag("`async` bound modifier only allowed on trait, not `{$descr}`")]
pub(crate) struct AsyncBoundNotOnTrait {
#[primary_span]
pub span: Span,
@ -426,30 +455,37 @@ pub(crate) struct AsyncBoundNotOnTrait {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_async_bound_only_for_fn_traits)]
#[diag("`async` bound modifier only allowed on `Fn`/`FnMut`/`FnOnce` traits")]
pub(crate) struct AsyncBoundOnlyForFnTraits {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_no_precise_captures_on_apit)]
#[diag("`use<...>` precise capturing syntax not allowed in argument-position `impl Trait`")]
pub(crate) struct NoPreciseCapturesOnApit {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_yield_in_closure)]
#[diag("`yield` can only be used in `#[coroutine]` closures, or `gen` blocks")]
pub(crate) struct YieldInClosure {
#[primary_span]
pub span: Span,
#[suggestion(code = "#[coroutine] ", applicability = "maybe-incorrect", style = "verbose")]
#[suggestion(
"use `#[coroutine]` to make this closure a coroutine",
code = "#[coroutine] ",
applicability = "maybe-incorrect",
style = "verbose"
)]
pub suggestion: Option<Span>,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_invalid_legacy_const_generic_arg)]
#[diag(
"invalid argument to a legacy const generic: cannot have const blocks, closures, async blocks or items"
)]
pub(crate) struct InvalidLegacyConstGenericArg {
#[primary_span]
pub span: Span,
@ -459,7 +495,7 @@ pub(crate) struct InvalidLegacyConstGenericArg {
#[derive(Subdiagnostic)]
#[multipart_suggestion(
ast_lowering_invalid_legacy_const_generic_arg_suggestion,
"try using a const generic argument instead",
applicability = "maybe-incorrect"
)]
pub(crate) struct UseConstGenericArg {
@ -472,21 +508,21 @@ pub(crate) struct UseConstGenericArg {
}
#[derive(Diagnostic)]
#[diag(ast_lowering_union_default_field_values)]
#[diag("unions cannot have default field values")]
pub(crate) struct UnionWithDefault {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_delegation_unresolved_callee)]
#[diag("failed to resolve delegation callee")]
pub(crate) struct UnresolvedDelegationCallee {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(ast_lowering_delegation_cycle_in_signature_resolution)]
#[diag("encountered a cycle during delegation signature resolution")]
pub(crate) struct CycleInDelegationSignatureResolution {
#[primary_span]
pub span: Span,

View file

@ -5,6 +5,7 @@ use std::sync::Arc;
use rustc_ast::*;
use rustc_ast_pretty::pprust::expr_to_string;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::inline_fluent;
use rustc_hir as hir;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{DefKind, Res};
@ -28,9 +29,7 @@ use super::{
GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt,
};
use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure};
use crate::{
AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope, fluent_generated,
};
use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope};
struct WillCreateDefIdsVisitor {}
@ -1703,7 +1702,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
&self.tcx.sess,
sym::yield_expr,
span,
fluent_generated::ast_lowering_yield,
inline_fluent!("yield syntax is experimental"),
)
.emit();
}

View file

@ -88,8 +88,6 @@ mod pat;
mod path;
pub mod stability;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
struct LoweringContext<'a, 'hir> {
tcx: TyCtxt<'hir>,
resolver: &'a mut ResolverAstLowering,

View file

@ -13,7 +13,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_macros = { path = "../rustc_macros" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }

View file

@ -1,342 +0,0 @@
ast_passes_abi_cannot_be_coroutine =
functions with the {$abi} ABI cannot be `{$coroutine_kind_str}`
.suggestion = remove the `{$coroutine_kind_str}` keyword from this definition
ast_passes_abi_custom_safe_foreign_function =
foreign functions with the "custom" ABI cannot be safe
.suggestion = remove the `safe` keyword from this definition
ast_passes_abi_custom_safe_function =
functions with the "custom" ABI must be unsafe
.suggestion = add the `unsafe` keyword to this definition
ast_passes_abi_must_not_have_parameters_or_return_type=
invalid signature for `extern {$abi}` function
.note = functions with the {$abi} ABI cannot have any parameters or return type
.suggestion = remove the parameters and return type
ast_passes_abi_must_not_have_return_type=
invalid signature for `extern {$abi}` function
.note = functions with the {$abi} ABI cannot have a return type
.help = remove the return type
ast_passes_abi_x86_interrupt =
invalid signature for `extern "x86-interrupt"` function
.note = functions with the "x86-interrupt" ABI must be have either 1 or 2 parameters (but found {$param_count})
ast_passes_assoc_const_without_body =
associated constant in `impl` without body
.suggestion = provide a definition for the constant
ast_passes_assoc_fn_without_body =
associated function in `impl` without body
.suggestion = provide a definition for the function
ast_passes_assoc_type_without_body =
associated type in `impl` without body
.suggestion = provide a definition for the type
ast_passes_async_fn_in_const_trait_or_trait_impl =
async functions are not allowed in `const` {$context ->
[trait_impl] trait impls
[impl] impls
*[trait] traits
}
.label = associated functions of `const` cannot be declared `async`
ast_passes_at_least_one_trait = at least one trait must be specified
ast_passes_auto_generic = auto traits cannot have generic parameters
.label = auto trait cannot have generic parameters
.suggestion = remove the parameters
ast_passes_auto_items = auto traits cannot have associated items
.label = {ast_passes_auto_items}
.suggestion = remove the associated items
ast_passes_auto_super_lifetime = auto traits cannot have super traits or lifetime bounds
.label = {ast_passes_auto_super_lifetime}
.suggestion = remove the super traits or lifetime bounds
ast_passes_body_in_extern = incorrect `{$kind}` inside `extern` block
.cannot_have = cannot have a body
.invalid = the invalid body
.existing = `extern` blocks define existing foreign {$kind}s and {$kind}s inside of them cannot have a body
ast_passes_bound_in_context = bounds on `type`s in {$ctx} have no effect
ast_passes_c_variadic_bad_extern = `...` is not supported for `extern "{$abi}"` functions
.label = `extern "{$abi}"` because of this
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
ast_passes_c_variadic_bad_naked_extern = `...` is not supported for `extern "{$abi}"` naked functions
.label = `extern "{$abi}"` because of this
.help = C-variadic function must have a compatible calling convention
ast_passes_c_variadic_must_be_unsafe =
functions with a C variable argument list must be unsafe
.suggestion = add the `unsafe` keyword to this definition
ast_passes_c_variadic_no_extern = `...` is not supported for non-extern functions
.help = only `extern "C"` and `extern "C-unwind"` functions may have a C variable argument list
ast_passes_c_variadic_not_supported = the `{$target}` target does not support c-variadic functions
ast_passes_const_and_c_variadic = functions cannot be both `const` and C-variadic
.const = `const` because of this
.variadic = C-variadic because of this
ast_passes_const_and_coroutine = functions cannot be both `const` and `{$coroutine_kind}`
.const = `const` because of this
.coroutine = `{$coroutine_kind}` because of this
.label = {""}
ast_passes_const_auto_trait = auto traits cannot be const
.help = remove the `const` keyword
ast_passes_const_bound_trait_object = const trait bounds are not allowed in trait object types
ast_passes_const_without_body =
free constant item without body
.suggestion = provide a definition for the constant
ast_passes_constraint_on_negative_bound =
associated type constraints not allowed on negative bounds
ast_passes_coroutine_and_c_variadic = functions cannot be both `{$coroutine_kind}` and C-variadic
.const = `{$coroutine_kind}` because of this
.variadic = C-variadic because of this
ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses
.label = not supported
.suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax
.suggestion_path = if `{$trait_segment}::{$potential_assoc}` is an associated type you're trying to set, use the associated type binding syntax
.note = see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
ast_passes_extern_block_suggestion = if you meant to declare an externally defined function, use an `extern` block
ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have `{$kw}` qualifier
.label = in this `extern` block
.suggestion = remove the `{$kw}` qualifier
ast_passes_extern_invalid_safety = items in `extern` blocks without an `unsafe` qualifier cannot have safety qualifiers
.suggestion = add `unsafe` to this `extern` block
ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
.label = in this `extern` block
.note = this limitation may be lifted in the future; see issue #83942 <https://github.com/rust-lang/rust/issues/83942> for more information
ast_passes_extern_keyword_link = for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$descr}
.suggestion = remove the {$remove_descr}
.label = `extern` block begins here
ast_passes_extern_without_abi = `extern` declarations without an explicit ABI are disallowed
.suggestion = specify an ABI
.help = prior to Rust 2024, a default ABI was inferred
ast_passes_extern_without_abi_sugg = `extern` declarations without an explicit ABI are deprecated
.label = ABI should be specified here
.suggestion = explicitly specify the {$default_abi} ABI
ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel
.suggestion = remove the attribute
.stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable
ast_passes_fieldless_union = unions cannot have zero fields
ast_passes_fn_body_extern = incorrect function inside `extern` block
.cannot_have = cannot have a body
.suggestion = remove the invalid body
.help = you might have meant to write a function accessible through FFI, which can be done by writing `extern fn` outside of the `extern` block
.label = `extern` blocks define existing foreign functions and functions inside of them cannot have a body
ast_passes_fn_param_c_var_args_not_last =
`...` must be the last argument of a C-variadic function
ast_passes_fn_param_doc_comment =
documentation comments cannot be applied to function parameters
.label = doc comments are not allowed here
ast_passes_fn_param_forbidden_attr =
allow, cfg, cfg_attr, deny, expect, forbid, and warn are the only allowed built-in attributes in function parameters
ast_passes_fn_param_forbidden_self =
`self` parameter is only allowed in associated functions
.label = not semantically valid as function parameter
.note = associated functions are those in `impl` or `trait` definitions
ast_passes_fn_param_too_many =
function can not have more than {$max_num_args} arguments
ast_passes_fn_ptr_invalid_safety = function pointers cannot be declared with `safe` safety qualifier
.suggestion = remove safe from this item
ast_passes_fn_without_body =
free function without a body
.suggestion = provide a definition for the function
ast_passes_forbidden_bound =
bounds cannot be used in this context
ast_passes_forbidden_const_param =
late-bound const parameters cannot be used currently
ast_passes_forbidden_default =
`default` is only allowed on items in trait impls
.label = `default` because of this
ast_passes_forbidden_non_lifetime_param =
only lifetime parameters can be used in this context
ast_passes_generic_before_constraints = generic arguments must come before the first constraint
.constraints = {$constraint_len ->
[one] constraint
*[other] constraints
}
.args = generic {$args_len ->
[one] argument
*[other] arguments
}
.empty_string = {""},
.suggestion = move the {$constraint_len ->
[one] constraint
*[other] constraints
} after the generic {$args_len ->
[one] argument
*[other] arguments
}
ast_passes_generic_default_trailing = generic parameters with a default must be trailing
ast_passes_impl_fn_const =
redundant `const` fn marker in const impl
.parent_constness = this declares all associated functions implicitly const
.label = remove the `const`
ast_passes_incompatible_features = `{$f1}` and `{$f2}` are incompatible, using them at the same time is not allowed
.help = remove one of these features
ast_passes_item_invalid_safety = items outside of `unsafe extern {"{ }"}` cannot be declared with `safe` safety qualifier
.suggestion = remove safe from this item
ast_passes_item_underscore = `{$kind}` items in this context need a name
.label = `_` is not a valid name for this `{$kind}` item
ast_passes_match_arm_with_no_body =
`match` arm with no body
.suggestion = add a body after the pattern
ast_passes_missing_unsafe_on_extern = extern blocks must be unsafe
.suggestion = needs `unsafe` before the extern keyword
ast_passes_missing_unsafe_on_extern_lint = extern blocks should be unsafe
.suggestion = needs `unsafe` before the extern keyword
ast_passes_module_nonascii = trying to load file for module `{$name}` with non-ascii identifier name
.help = consider using the `#[path]` attribute to specify filesystem path
ast_passes_negative_bound_not_supported =
negative bounds are not supported
ast_passes_negative_bound_with_parenthetical_notation =
parenthetical notation may not be used for negative bounds
ast_passes_nested_impl_trait = nested `impl Trait` is not allowed
.outer = outer `impl Trait`
.inner = nested `impl Trait` here
ast_passes_nested_lifetimes = nested quantification of lifetimes
ast_passes_nomangle_ascii = `#[no_mangle]` requires ASCII identifier
ast_passes_obsolete_auto = `impl Trait for .. {"{}"}` is an obsolete syntax
.help = use `auto trait Trait {"{}"}` instead
ast_passes_out_of_order_params = {$param_ord} parameters must be declared prior to {$max_param} parameters
.suggestion = reorder the parameters: lifetimes, then consts and types
ast_passes_pattern_in_bodiless = patterns aren't allowed in functions without bodies
.label = pattern not allowed in function without body
ast_passes_pattern_in_fn_pointer = patterns aren't allowed in function pointer types
ast_passes_pattern_in_foreign = patterns aren't allowed in foreign function declarations
.label = pattern not allowed in foreign function
ast_passes_precise_capturing_duplicated = duplicate `use<...>` precise capturing syntax
.label = second `use<...>` here
ast_passes_precise_capturing_not_allowed_here = `use<...>` precise capturing syntax not allowed in {$loc}
ast_passes_scalable_vector_not_tuple_struct = scalable vectors must be tuple structs
ast_passes_static_without_body =
free static item without body
.suggestion = provide a definition for the static
ast_passes_tilde_const_disallowed = `[const]` is not allowed here
.closure = closures cannot have `[const]` trait bounds
.function = this function is not `const`, so it cannot have `[const]` trait bounds
.trait = this trait is not `const`, so it cannot have `[const]` trait bounds
.trait_impl = this impl is not `const`, so it cannot have `[const]` trait bounds
.impl = inherent impls cannot have `[const]` trait bounds
.trait_assoc_ty = associated types in non-`const` traits cannot have `[const]` trait bounds
.trait_impl_assoc_ty = associated types in non-const impls cannot have `[const]` trait bounds
.inherent_assoc_ty = inherent associated types cannot have `[const]` trait bounds
.struct = structs cannot have `[const]` trait bounds
.enum = enums cannot have `[const]` trait bounds
.union = unions cannot have `[const]` trait bounds
.anon_const = anonymous constants cannot have `[const]` trait bounds
.object = trait objects cannot have `[const]` trait bounds
.item = this item cannot have `[const]` trait bounds
ast_passes_trait_fn_const =
functions in {$in_impl ->
[true] trait impls
*[false] traits
} cannot be declared const
.label = functions in {$in_impl ->
[true] trait impls
*[false] traits
} cannot be const
.const_context_label = this declares all associated functions implicitly const
.remove_const_sugg = remove the `const`{$requires_multiple_changes ->
[true] {" ..."}
*[false] {""}
}
.make_impl_const_sugg = ... and declare the impl to be const instead
.make_trait_const_sugg = ... and declare the trait to be const instead
ast_passes_trait_object_single_bound = only a single explicit lifetime bound is permitted
ast_passes_ty_alias_without_body =
free type alias without body
.suggestion = provide a definition for the type
ast_passes_unsafe_item = {$kind} cannot be declared unsafe
ast_passes_unsafe_negative_impl = negative impls cannot be unsafe
.negative = negative because of this
.unsafe = unsafe because of this
ast_passes_unsafe_static =
static items cannot be declared with `unsafe` safety qualifier outside of `extern` block
ast_passes_visibility_not_permitted =
visibility qualifiers are not permitted here
.enum_variant = enum variants and their fields always share the visibility of the enum they are in
.trait_impl = trait items always share the visibility of their trait
.individual_impl_items = place qualifiers on individual impl items instead
.individual_foreign_items = place qualifiers on individual foreign items instead
.remove_qualifier_sugg = remove the qualifier
ast_passes_where_clause_after_type_alias = where clauses are not allowed after the type for type aliases
.note = see issue #112792 <https://github.com/rust-lang/rust/issues/112792> for more information
.help = add `#![feature(lazy_type_alias)]` to the crate attributes to enable
ast_passes_where_clause_before_type_alias = where clauses are not allowed before the type for type aliases
.note = see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information
.remove_suggestion = remove this `where`
.move_suggestion = move it to the end of the type declaration

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,6 @@
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{self as ast, AttrVec, NodeId, PatKind, attr, token};
use rustc_errors::inline_fluent;
use rustc_feature::{AttributeGate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, Features};
use rustc_session::Session;
use rustc_session::parse::{feature_err, feature_warn};
@ -124,7 +125,7 @@ impl<'a> PostExpansionVisitor<'a> {
&self,
non_lifetime_binders,
non_lt_param_spans,
crate::fluent_generated::ast_passes_forbidden_non_lifetime_param
inline_fluent!("only lifetime parameters can be used in this context")
);
// FIXME(non_lifetime_binders): Const bound params are pretty broken.

View file

@ -11,5 +11,3 @@
pub mod ast_validation;
mod errors;
pub mod feature_gate;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -1,12 +1,16 @@
use std::path::PathBuf;
use rustc_ast::{LitIntType, LitKind, MetaItemLit};
use rustc_hir::attrs::{BorrowckGraphvizFormatKind, RustcLayoutType, RustcMirKind};
use rustc_hir::attrs::{
BorrowckGraphvizFormatKind, RustcCleanAttribute, RustcCleanQueries, RustcLayoutType,
RustcMirKind,
};
use rustc_session::errors;
use rustc_span::Symbol;
use super::prelude::*;
use super::util::parse_single_integer;
use crate::session_diagnostics::RustcScalableVectorCountOutOfRange;
use crate::session_diagnostics::{AttributeRequiresOpt, RustcScalableVectorCountOutOfRange};
pub(crate) struct RustcMainParser;
@ -234,7 +238,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcLintUntrackedQueryInformationPa
pub(crate) struct RustcObjectLifetimeDefaultParser;
impl<S: Stage> SingleAttributeParser<S> for RustcObjectLifetimeDefaultParser {
const PATH: &[rustc_span::Symbol] = &[sym::rustc_object_lifetime_default];
const PATH: &[Symbol] = &[sym::rustc_object_lifetime_default];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
@ -271,7 +275,7 @@ impl<S: Stage> SingleAttributeParser<S> for RustcSimdMonomorphizeLaneLimitParser
pub(crate) struct RustcScalableVectorParser;
impl<S: Stage> SingleAttributeParser<S> for RustcScalableVectorParser {
const PATH: &[rustc_span::Symbol] = &[sym::rustc_scalable_vector];
const PATH: &[Symbol] = &[sym::rustc_scalable_vector];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepInnermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
@ -344,7 +348,7 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcOffloadKernelParser {
pub(crate) struct RustcLayoutParser;
impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
const PATH: &[rustc_span::Symbol] = &[sym::rustc_layout];
const PATH: &[Symbol] = &[sym::rustc_layout];
type Item = RustcLayoutType;
@ -401,7 +405,7 @@ impl<S: Stage> CombineAttributeParser<S> for RustcLayoutParser {
pub(crate) struct RustcMirParser;
impl<S: Stage> CombineAttributeParser<S> for RustcMirParser {
const PATH: &[rustc_span::Symbol] = &[sym::rustc_mir];
const PATH: &[Symbol] = &[sym::rustc_mir];
type Item = RustcMirKind;
@ -497,3 +501,223 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcNonConstTraitMethodParser {
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonConstTraitMethod;
}
pub(crate) struct RustcCleanParser;
impl<S: Stage> CombineAttributeParser<S> for RustcCleanParser {
const PATH: &[Symbol] = &[sym::rustc_clean];
type Item = RustcCleanAttribute;
const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcClean(items);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
// tidy-alphabetical-start
Allow(Target::AssocConst),
Allow(Target::AssocTy),
Allow(Target::Const),
Allow(Target::Enum),
Allow(Target::Expression),
Allow(Target::Field),
Allow(Target::Fn),
Allow(Target::ForeignMod),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Mod),
Allow(Target::Static),
Allow(Target::Struct),
Allow(Target::Trait),
Allow(Target::TyAlias),
Allow(Target::Union),
// tidy-alphabetical-end
]);
const TEMPLATE: AttributeTemplate =
template!(List: &[r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#]);
fn extend(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser,
) -> impl IntoIterator<Item = Self::Item> {
if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
}
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span, args);
return None;
};
let mut except = None;
let mut loaded_from_disk = None;
let mut cfg = None;
for item in list.mixed() {
let Some((value, name)) =
item.meta_item().and_then(|m| Option::zip(m.args().name_value(), m.ident()))
else {
cx.expected_name_value(item.span(), None);
continue;
};
let value_span = value.value_span;
let Some(value) = value.value_as_str() else {
cx.expected_string_literal(value_span, None);
continue;
};
match name.name {
sym::cfg if cfg.is_some() => {
cx.duplicate_key(item.span(), sym::cfg);
}
sym::cfg => {
cfg = Some(value);
}
sym::except if except.is_some() => {
cx.duplicate_key(item.span(), sym::except);
}
sym::except => {
let entries =
value.as_str().split(',').map(|s| Symbol::intern(s.trim())).collect();
except = Some(RustcCleanQueries { entries, span: value_span });
}
sym::loaded_from_disk if loaded_from_disk.is_some() => {
cx.duplicate_key(item.span(), sym::loaded_from_disk);
}
sym::loaded_from_disk => {
let entries =
value.as_str().split(',').map(|s| Symbol::intern(s.trim())).collect();
loaded_from_disk = Some(RustcCleanQueries { entries, span: value_span });
}
_ => {
cx.expected_specific_argument(
name.span,
&[sym::cfg, sym::except, sym::loaded_from_disk],
);
}
}
}
let Some(cfg) = cfg else {
cx.expected_specific_argument(list.span, &[sym::cfg]);
return None;
};
Some(RustcCleanAttribute { span: cx.attr_span, cfg, except, loaded_from_disk })
}
}
pub(crate) struct RustcIfThisChangedParser;
impl<S: Stage> SingleAttributeParser<S> for RustcIfThisChangedParser {
const PATH: &[Symbol] = &[sym::rustc_if_this_changed];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
// tidy-alphabetical-start
Allow(Target::AssocConst),
Allow(Target::AssocTy),
Allow(Target::Const),
Allow(Target::Enum),
Allow(Target::Expression),
Allow(Target::Field),
Allow(Target::Fn),
Allow(Target::ForeignMod),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Mod),
Allow(Target::Static),
Allow(Target::Struct),
Allow(Target::Trait),
Allow(Target::TyAlias),
Allow(Target::Union),
// tidy-alphabetical-end
]);
const TEMPLATE: AttributeTemplate = template!(Word, List: &["DepNode"]);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
}
match args {
ArgParser::NoArgs => Some(AttributeKind::RustcIfThisChanged(cx.attr_span, None)),
ArgParser::List(list) => {
let Some(item) = list.single() else {
cx.expected_single_argument(list.span);
return None;
};
let Some(ident) = item.meta_item().and_then(|item| item.ident()) else {
cx.expected_identifier(item.span());
return None;
};
Some(AttributeKind::RustcIfThisChanged(cx.attr_span, Some(ident.name)))
}
ArgParser::NameValue(_) => {
cx.expected_list_or_no_args(cx.inner_span);
None
}
}
}
}
pub(crate) struct RustcThenThisWouldNeedParser;
impl<S: Stage> CombineAttributeParser<S> for RustcThenThisWouldNeedParser {
const PATH: &[Symbol] = &[sym::rustc_then_this_would_need];
type Item = Ident;
const CONVERT: ConvertFn<Self::Item> =
|items, span| AttributeKind::RustcThenThisWouldNeed(span, items);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
// tidy-alphabetical-start
Allow(Target::AssocConst),
Allow(Target::AssocTy),
Allow(Target::Const),
Allow(Target::Enum),
Allow(Target::Expression),
Allow(Target::Field),
Allow(Target::Fn),
Allow(Target::ForeignMod),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::Mod),
Allow(Target::Static),
Allow(Target::Struct),
Allow(Target::Trait),
Allow(Target::TyAlias),
Allow(Target::Union),
// tidy-alphabetical-end
]);
const TEMPLATE: AttributeTemplate = template!(List: &["DepNode"]);
fn extend(
cx: &mut AcceptContext<'_, '_, S>,
args: &ArgParser,
) -> impl IntoIterator<Item = Self::Item> {
if !cx.cx.sess.opts.unstable_opts.query_dep_graph {
cx.emit_err(AttributeRequiresOpt { span: cx.attr_span, opt: "-Z query-dep-graph" });
}
let Some(item) = args.list().and_then(|l| l.single()) else {
cx.expected_single_argument(cx.inner_span);
return None;
};
let Some(ident) = item.meta_item().and_then(|item| item.ident()) else {
cx.expected_identifier(item.span());
return None;
};
Some(ident)
}
}

View file

@ -113,3 +113,30 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcVarianceOfOpaquesParser {
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVarianceOfOpaques;
}
pub(crate) struct ReexportTestHarnessMainParser;
impl<S: Stage> SingleAttributeParser<S> for ReexportTestHarnessMainParser {
const PATH: &[Symbol] = &[sym::reexport_test_harness_main];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(nv) = args.name_value() else {
cx.expected_name_value(
args.span().unwrap_or(cx.inner_span),
Some(sym::reexport_test_harness_main),
);
return None;
};
let Some(name) = nv.value_as_str() else {
cx.expected_string_literal(nv.value_span, Some(nv.value_as_lit()));
return None;
};
Some(AttributeKind::ReexportTestHarnessMain(name))
}
}

View file

@ -153,8 +153,10 @@ attribute_parsers!(
Combine<ForceTargetFeatureParser>,
Combine<LinkParser>,
Combine<ReprParser>,
Combine<RustcCleanParser>,
Combine<RustcLayoutParser>,
Combine<RustcMirParser>,
Combine<RustcThenThisWouldNeedParser>,
Combine<TargetFeatureParser>,
Combine<UnstableFeatureBoundParser>,
// tidy-alphabetical-end
@ -188,9 +190,11 @@ attribute_parsers!(
Single<PatternComplexityLimitParser>,
Single<ProcMacroDeriveParser>,
Single<RecursionLimitParser>,
Single<ReexportTestHarnessMainParser>,
Single<RustcAllocatorZeroedVariantParser>,
Single<RustcBuiltinMacroParser>,
Single<RustcForceInlineParser>,
Single<RustcIfThisChangedParser>,
Single<RustcLayoutScalarValidRangeEndParser>,
Single<RustcLayoutScalarValidRangeStartParser>,
Single<RustcLegacyConstGenericsParser>,

View file

@ -532,6 +532,14 @@ pub(crate) struct RustcScalableVectorCountOutOfRange {
pub n: u128,
}
#[derive(Diagnostic)]
#[diag("attribute requires {$opt} to be enabled")]
pub(crate) struct AttributeRequiresOpt {
#[primary_span]
pub span: Span,
pub opt: &'static str,
}
pub(crate) enum AttributeParseErrorReason<'a> {
ExpectedNoArgs,
ExpectedStringLiteral {

View file

@ -1256,7 +1256,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.suggest_cloning_inner(err, ty, expr);
}
} else if let ty::Adt(def, args) = ty.kind()
&& def.did().as_local().is_some()
&& let Some(local_did) = def.did().as_local()
&& def.variants().iter().all(|variant| {
variant
.fields
@ -1266,12 +1266,50 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
{
let ty_span = self.infcx.tcx.def_span(def.did());
let mut span: MultiSpan = ty_span.into();
span.push_span_label(ty_span, "consider implementing `Clone` for this type");
span.push_span_label(expr.span, "you could clone this value");
err.span_note(
span,
format!("if `{ty}` implemented `Clone`, you could clone the value"),
let mut derive_clone = false;
self.infcx.tcx.for_each_relevant_impl(
self.infcx.tcx.lang_items().clone_trait().unwrap(),
ty,
|def_id| {
if self.infcx.tcx.is_automatically_derived(def_id) {
derive_clone = true;
span.push_span_label(
self.infcx.tcx.def_span(def_id),
"derived `Clone` adds implicit bounds on type parameters",
);
if let Some(generics) = self.infcx.tcx.hir_get_generics(local_did) {
for param in generics.params {
if let hir::GenericParamKind::Type { .. } = param.kind {
span.push_span_label(
param.span,
format!(
"introduces an implicit `{}: Clone` bound",
param.name.ident()
),
);
}
}
}
}
},
);
let msg = if !derive_clone {
span.push_span_label(
ty_span,
format!(
"consider {}implementing `Clone` for this type",
if derive_clone { "manually " } else { "" }
),
);
format!("if `{ty}` implemented `Clone`, you could clone the value")
} else {
format!("if all bounds were met, you could clone the value")
};
span.push_span_label(expr.span, "you could clone this value");
err.span_note(span, msg);
if derive_clone {
err.help("consider manually implementing `Clone` to avoid undesired bounds");
}
} else if let ty::Param(param) = ty.kind()
&& let Some(_clone_trait_def) = self.infcx.tcx.lang_items().clone_trait()
&& let generics = self.infcx.tcx.generics_of(self.mir_def_id())

View file

@ -15,7 +15,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_lexer = { path = "../rustc_lexer" }

View file

@ -1,320 +0,0 @@
builtin_macros_alloc_error_must_be_fn = alloc_error_handler must be a function
builtin_macros_alloc_must_statics = allocators must be statics
builtin_macros_asm_attribute_not_supported =
this attribute is not supported on assembly
builtin_macros_asm_clobber_abi = clobber_abi
builtin_macros_asm_clobber_no_reg = asm with `clobber_abi` must specify explicit registers for outputs
builtin_macros_asm_clobber_outputs = generic outputs
builtin_macros_asm_duplicate_arg = duplicate argument named `{$name}`
.label = previously here
.arg = duplicate argument
builtin_macros_asm_explicit_register_name = explicit register arguments cannot have names
builtin_macros_asm_mayunwind = asm labels are not allowed with the `may_unwind` option
builtin_macros_asm_modifier_invalid = asm template modifier must be a single character
builtin_macros_asm_mutually_exclusive = the `{$opt1}` and `{$opt2}` options are mutually exclusive
builtin_macros_asm_no_matched_argument_name = there is no argument named `{$name}`
builtin_macros_asm_noreturn = asm outputs are not allowed with the `noreturn` option
builtin_macros_asm_opt_already_provided = the `{$symbol}` option was already provided
.label = this option was already provided
.suggestion = remove this option
builtin_macros_asm_pos_after = positional arguments cannot follow named arguments or explicit register arguments
.pos = positional argument
.named = named argument
.explicit = explicit register argument
builtin_macros_asm_pure_combine = the `pure` option must be combined with either `nomem` or `readonly`
builtin_macros_asm_pure_no_output = asm with the `pure` option must have at least one output
builtin_macros_asm_unsupported_clobber_abi = `clobber_abi` cannot be used with `{$macro_name}!`
builtin_macros_asm_unsupported_option = the `{$symbol}` option cannot be used with `{$macro_name}!`
.label = the `{$symbol}` option is not meaningful for global-scoped inline assembly
.suggestion = remove this option
builtin_macros_assert_missing_comma = unexpected string literal
.suggestion = try adding a comma
builtin_macros_assert_requires_boolean = macro requires a boolean expression as an argument
.label = boolean expression required
builtin_macros_assert_requires_expression = macro requires an expression as an argument
.suggestion = try removing semicolon
builtin_macros_autodiff = autodiff must be applied to function
builtin_macros_autodiff_missing_config = autodiff requires at least a name and mode
builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode
builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found}
builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode
builtin_macros_autodiff_ty_activity = {$act} can not be used for this type
builtin_macros_autodiff_unknown_activity = did not recognize Activity: `{$act}`
builtin_macros_autodiff_width = autodiff width must fit u32, but is {$width}
builtin_macros_avoid_att_syntax = avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
builtin_macros_avoid_intel_syntax = avoid using `.intel_syntax`, Intel syntax is the default
builtin_macros_bad_derive_target = `derive` may only be applied to `struct`s, `enum`s and `union`s
.label = not applicable here
.label2 = not a `struct`, `enum` or `union`
builtin_macros_bench_sig = functions used as benches must have signature `fn(&mut Bencher) -> impl Termination`
builtin_macros_cannot_derive_union = this trait cannot be derived for unions
builtin_macros_cfg_accessible_has_args = `cfg_accessible` path cannot accept arguments
builtin_macros_cfg_accessible_indeterminate = cannot determine whether the path is accessible or not
builtin_macros_cfg_accessible_literal_path = `cfg_accessible` path cannot be a literal
builtin_macros_cfg_accessible_multiple_paths = multiple `cfg_accessible` paths are specified
builtin_macros_cfg_accessible_unspecified_path = `cfg_accessible` path is not specified
builtin_macros_cfg_select_no_matches = none of the predicates in this `cfg_select` evaluated to true
builtin_macros_cfg_select_unreachable = unreachable predicate
.label = always matches
.label2 = this predicate is never reached
builtin_macros_coerce_pointee_requires_maybe_sized = `derive(CoercePointee)` requires `{$name}` to be marked `?Sized`
builtin_macros_coerce_pointee_requires_one_field = `CoercePointee` can only be derived on `struct`s with at least one field
builtin_macros_coerce_pointee_requires_one_generic = `CoercePointee` can only be derived on `struct`s that are generic over at least one type
builtin_macros_coerce_pointee_requires_one_pointee = exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits
builtin_macros_coerce_pointee_requires_transparent = `CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`
builtin_macros_coerce_pointee_too_many_pointees = only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits
.label = here another type parameter is marked as `#[pointee]`
builtin_macros_concat_bytes_array = cannot concatenate doubly nested array
.note = byte strings are treated as arrays of bytes
.help = try flattening the array
builtin_macros_concat_bytes_bad_repeat = repeat count is not a positive number
builtin_macros_concat_bytes_invalid = cannot concatenate {$lit_kind} literals
.byte_char = try using a byte character
.byte_str = try using a byte string
.c_str = try using a null-terminated byte string
.c_str_note = concatenating C strings is ambiguous about including the '\0'
.number_array = try wrapping the number in an array
builtin_macros_concat_bytes_missing_literal = expected a byte literal
.note = only byte literals (like `b"foo"`, `b's'` and `[3, 4, 5]`) can be passed to `concat_bytes!()`
builtin_macros_concat_bytes_non_u8 = numeric literal is not a `u8`
builtin_macros_concat_bytes_oob = numeric literal is out of bounds
builtin_macros_concat_bytestr = cannot concatenate a byte string literal
builtin_macros_concat_c_str_lit = cannot concatenate a C string literal
builtin_macros_concat_missing_literal = expected a literal
.note = only literals (like `"foo"`, `-42` and `3.14`) can be passed to `concat!()`
builtin_macros_default_arg = `#[default]` attribute does not accept a value
.suggestion = try using `#[default]`
builtin_macros_derive_from_usage_note = `#[derive(From)]` can only be used on structs with exactly one field
builtin_macros_derive_from_wrong_field_count = `#[derive(From)]` used on a struct with {$multiple_fields ->
[true] multiple fields
*[false] no fields
}
builtin_macros_derive_from_wrong_target = `#[derive(From)]` used on {$kind}
builtin_macros_derive_macro_call = `derive` cannot be used on items with type macros
builtin_macros_derive_path_args_list = traits in `#[derive(...)]` don't accept arguments
.suggestion = remove the arguments
builtin_macros_derive_path_args_value = traits in `#[derive(...)]` don't accept values
.suggestion = remove the value
builtin_macros_duplicate_macro_attribute = duplicated attribute
builtin_macros_eii_declaration_expected_list = `#[eii_declaration(...)]` expects a list of one or two elements
builtin_macros_eii_declaration_expected_macro = `#[eii_declaration(...)]` is only valid on macros
builtin_macros_eii_declaration_expected_unsafe = expected this argument to be "unsafe"
.note = the second argument is optional
builtin_macros_eii_only_once = `#[{$name}]` can only be specified once
.note = specified again here
builtin_macros_eii_shared_macro_expected_function = `#[{$name}]` is only valid on functions
builtin_macros_eii_shared_macro_expected_max_one_argument = `#[{$name}]` expected no arguments or a single argument: `#[{$name}(default)]`
builtin_macros_eii_shared_macro_in_statement_position = `#[{$name}]` can only be used on functions inside a module
.label = `#[{$name}]` is used on this item, which is part of another item's local scope
builtin_macros_env_not_defined = environment variable `{$var}` not defined at compile time
.cargo = Cargo sets build script variables at run time. Use `std::env::var({$var_expr})` instead
.cargo_typo = there is a similar Cargo environment variable: `{$suggested_var}`
.custom = use `std::env::var({$var_expr})` to read the variable at run time
builtin_macros_env_not_unicode = environment variable `{$var}` is not a valid Unicode string
builtin_macros_env_takes_args = `env!()` takes 1 or 2 arguments
builtin_macros_expected_comma_in_list = expected token: `,`
builtin_macros_expected_one_cfg_pattern = expected 1 cfg-pattern
builtin_macros_expected_other = expected operand, {$is_inline_asm ->
[false] options
*[true] clobber_abi, options
}, or additional template string
builtin_macros_export_macro_rules = cannot export macro_rules! macros from a `proc-macro` crate type currently
builtin_macros_format_add_missing_colon = add a colon before the format specifier
builtin_macros_format_duplicate_arg = duplicate argument named `{$ident}`
.label1 = previously here
.label2 = duplicate argument
builtin_macros_format_no_arg_named = there is no argument named `{$name}`
.note = did you intend to capture a variable `{$name}` from the surrounding scope?
.note2 = to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro
builtin_macros_format_pos_mismatch = {$n} positional {$n ->
[one] argument
*[more] arguments
} in format string, but {$desc}
builtin_macros_format_positional_after_named = positional arguments cannot follow named arguments
.label = positional arguments must be before named arguments
.named_args = named argument
builtin_macros_format_redundant_args = redundant {$n ->
[one] argument
*[more] arguments
}
.help = {$n ->
[one] the formatting string already captures the binding directly, it doesn't need to be included in the argument list
*[more] the formatting strings already captures the bindings directly, they don't need to be included in the argument list
}
.note = {$n ->
[one] the formatting specifier is referencing the binding already
*[more] the formatting specifiers are referencing the bindings already
}
.suggestion = this can be removed
builtin_macros_format_remove_raw_ident = remove the `r#`
builtin_macros_format_reorder_format_parameter = did you mean `{$replacement}`?
builtin_macros_format_requires_string = requires at least a format string argument
builtin_macros_format_string_invalid = invalid format string: {$desc}
.label = {$label1} in format string
.note = {$note}
.second_label = {$label}
builtin_macros_format_unknown_trait = unknown format trait `{$ty}`
.note = the only appropriate formatting traits are:
- ``, which uses the `Display` trait
- `?`, which uses the `Debug` trait
- `e`, which uses the `LowerExp` trait
- `E`, which uses the `UpperExp` trait
- `o`, which uses the `Octal` trait
- `p`, which uses the `Pointer` trait
- `b`, which uses the `Binary` trait
- `x`, which uses the `LowerHex` trait
- `X`, which uses the `UpperHex` trait
.suggestion = use the `{$trait_name}` trait
builtin_macros_format_unused_arg = {$named ->
[true] named argument
*[false] argument
} never used
builtin_macros_format_unused_args = multiple unused formatting arguments
.label = multiple missing formatting specifiers
builtin_macros_format_use_positional = consider using a positional formatting argument instead
builtin_macros_incomplete_include = include macro expected single expression in source
builtin_macros_multiple_default_attrs = multiple `#[default]` attributes
.note = only one `#[default]` attribute is needed
.label = `#[default]` used here
.label_again = `#[default]` used again here
.help = try removing {$only_one ->
[true] this
*[false] these
}
builtin_macros_multiple_defaults = multiple declared defaults
.label = first default
.additional = additional default
.note = only one variant can be default
.suggestion = make `{$ident}` default
builtin_macros_naked_functions_testing_attribute =
cannot use `#[unsafe(naked)]` with testing attributes
.label = function marked with testing attribute here
.naked_attribute = `#[unsafe(naked)]` is incompatible with testing attributes
builtin_macros_no_default_variant = `#[derive(Default)]` on enum with no `#[default]`
.label = this enum needs a unit variant marked with `#[default]`
.suggestion = make this unit variant default by placing `#[default]` on it
builtin_macros_non_exhaustive_default = default variant must be exhaustive
.label = declared `#[non_exhaustive]` here
.help = consider a manual implementation of `Default`
builtin_macros_non_generic_pointee = the `#[pointee]` attribute may only be used on generic parameters
builtin_macros_non_unit_default = the `#[default]` attribute may only be used on unit enum variants{$post}
.help = consider a manual implementation of `Default`
builtin_macros_only_one_argument = {$name} takes 1 argument
builtin_macros_proc_macro = `proc-macro` crate types currently cannot export any items other than functions tagged with `#[proc_macro]`, `#[proc_macro_derive]`, or `#[proc_macro_attribute]`
builtin_macros_proc_macro_attribute_only_usable_with_crate_type = the `#[{$path}]` attribute is only usable with crates of the `proc-macro` crate type
builtin_macros_requires_cfg_pattern =
macro requires a cfg-pattern as an argument
.label = cfg-pattern required
builtin_macros_source_utils_expected_item = expected item, found `{$token}`
builtin_macros_takes_no_arguments = {$name} takes no arguments
builtin_macros_test_bad_fn = {$kind} functions cannot be used for tests
.label = `{$kind}` because of this
builtin_macros_test_case_non_item = `#[test_case]` attribute is only allowed on items
builtin_macros_test_runner_invalid = `test_runner` argument must be a path
builtin_macros_test_runner_nargs = `#![test_runner(..)]` accepts exactly 1 argument
builtin_macros_tests_not_support = building tests with panic=abort is not supported without `-Zpanic_abort_tests`
builtin_macros_trace_macros = trace_macros! accepts only `true` or `false`
builtin_macros_unexpected_lit = expected path to a trait, found literal
.label = not a trait
.str_lit = try using `#[derive({$sym})]`
.other = for example, write `#[derive(Debug)]` for `Debug`
builtin_macros_unnameable_test_items = cannot test inner items

View file

@ -463,44 +463,44 @@ impl<'a, 'b> rustc_ast::visit::Visitor<'a> for AlwaysErrorOnGenericParam<'a, 'b>
}
#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_transparent, code = E0802)]
#[diag("`CoercePointee` can only be derived on `struct`s with `#[repr(transparent)]`", code = E0802)]
struct RequireTransparent {
#[primary_span]
span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_one_field, code = E0802)]
#[diag("`CoercePointee` can only be derived on `struct`s with at least one field", code = E0802)]
struct RequireOneField {
#[primary_span]
span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_one_generic, code = E0802)]
#[diag("`CoercePointee` can only be derived on `struct`s that are generic over at least one type", code = E0802)]
struct RequireOneGeneric {
#[primary_span]
span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_one_pointee, code = E0802)]
#[diag("exactly one generic type parameter must be marked as `#[pointee]` to derive `CoercePointee` traits", code = E0802)]
struct RequireOnePointee {
#[primary_span]
span: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_too_many_pointees, code = E0802)]
#[diag("only one type parameter can be marked as `#[pointee]` when deriving `CoercePointee` traits", code = E0802)]
struct TooManyPointees {
#[primary_span]
one: Span,
#[label]
#[label("here another type parameter is marked as `#[pointee]`")]
another: Span,
}
#[derive(Diagnostic)]
#[diag(builtin_macros_coerce_pointee_requires_maybe_sized, code = E0802)]
#[diag("`derive(CoercePointee)` requires `{$name}` to be marked `?Sized`", code = E0802)]
struct RequiresMaybeSized {
#[primary_span]
span: Span,

View file

@ -638,27 +638,27 @@ impl<'a> TraitDef<'a> {
GenericParamKind::Type { .. } => {
// Extra restrictions on the generics parameters to the
// type being derived upon.
let span = param.ident.span.with_ctxt(ctxt);
let bounds: Vec<_> = self
.additional_bounds
.iter()
.map(|p| {
cx.trait_bound(
p.to_path(cx, self.span, type_ident, generics),
self.is_const,
)
cx.trait_bound(p.to_path(cx, span, type_ident, generics), self.is_const)
})
.chain(
// Add a bound for the current trait.
self.skip_path_as_bound
.not()
.then(|| cx.trait_bound(trait_path.clone(), self.is_const)),
self.skip_path_as_bound.not().then(|| {
let mut trait_path = trait_path.clone();
trait_path.span = span;
cx.trait_bound(trait_path, self.is_const)
}),
)
.chain({
// Add a `Copy` bound if required.
if is_packed && self.needs_copy_as_bound_if_packed {
let p = deriving::path_std!(marker::Copy);
Some(cx.trait_bound(
p.to_path(cx, self.span, type_ident, generics),
p.to_path(cx, span, type_ident, generics),
self.is_const,
))
} else {
@ -671,7 +671,7 @@ impl<'a> TraitDef<'a> {
)
.collect();
cx.typaram(param.ident.span.with_ctxt(ctxt), param.ident, bounds, None)
cx.typaram(span, param.ident, bounds, None)
}
GenericParamKind::Const { ty, span, .. } => {
let const_nodefault_kind = GenericParamKind::Const {
@ -791,7 +791,8 @@ impl<'a> TraitDef<'a> {
.collect();
// Create the type of `self`.
let path = cx.path_all(self.span, false, vec![type_ident], self_params);
let path =
cx.path_all(type_ident.span.with_ctxt(ctxt), false, vec![type_ident], self_params);
let self_type = cx.ty_path(path);
let rustc_const_unstable =
cx.path_ident(self.span, Ident::new(sym::rustc_const_unstable, self.span));

File diff suppressed because it is too large Load diff

View file

@ -57,8 +57,6 @@ pub mod standard_library_imports;
pub mod test_harness;
pub mod util;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
let mut register = |name, kind| resolver.register_builtin_macro(name, kind);
macro register_bang($($name:ident: $f:expr,)*) {

View file

@ -399,7 +399,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
for piece in template {
match *piece {
InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s),
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => {
InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span } => {
match operands[operand_idx] {
GlobalAsmOperandRef::Const { ref string } => {
// Const operands get injected directly into the
@ -414,7 +414,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&symbol);
template_str.push_str(&escape_symbol_name(self, symbol, span));
}
GlobalAsmOperandRef::SymStatic { def_id } => {
let llval = self
@ -428,7 +428,7 @@ impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
llvm::LLVMRustGetMangledName(llval, s);
})
.expect("symbol is not valid UTF-8");
template_str.push_str(&symbol);
template_str.push_str(&escape_symbol_name(self, symbol, span));
}
}
}
@ -1390,3 +1390,42 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
_ => layout.llvm_type(cx),
}
}
fn escape_symbol_name<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, symbol: String, span: Span) -> String {
use rustc_target::spec::{Arch, BinaryFormat};
if !symbol.is_empty()
&& symbol.chars().all(|c| matches!(c, '0'..='9' | 'A'..='Z' | 'a'..='z' | '_' | '$' | '.'))
{
return symbol;
}
if cx.tcx.sess.target.binary_format == BinaryFormat::Xcoff {
cx.tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the binary format {}",
cx.tcx.sess.target.binary_format
),
);
}
if cx.tcx.sess.target.arch == Arch::Nvptx64 {
cx.tcx.sess.dcx().span_fatal(
span,
format!(
"symbol escaping is not supported for the architecture {}",
cx.tcx.sess.target.arch
),
);
}
let mut escaped_symbol = String::new();
escaped_symbol.push('\"');
for c in symbol.chars() {
match c {
'\n' => escaped_symbol.push_str("\\\n"),
'"' => escaped_symbol.push_str("\\\""),
'\\' => escaped_symbol.push_str("\\\\"),
c => escaped_symbol.push(c),
}
}
escaped_symbol.push('\"');
escaped_symbol
}

View file

@ -347,7 +347,6 @@ pub(crate) struct OffloadKernelGlobals<'ll> {
pub offload_sizes: &'ll llvm::Value,
pub memtransfer_types: &'ll llvm::Value,
pub region_id: &'ll llvm::Value,
pub offload_entry: &'ll llvm::Value,
}
fn gen_tgt_data_mappers<'ll>(
@ -468,8 +467,12 @@ pub(crate) fn gen_define_handling<'ll>(
let c_section_name = CString::new("llvm_offload_entries").unwrap();
llvm::set_section(offload_entry, &c_section_name);
let result =
OffloadKernelGlobals { offload_sizes, memtransfer_types, region_id, offload_entry };
cx.add_compiler_used_global(offload_entry);
let result = OffloadKernelGlobals { offload_sizes, memtransfer_types, region_id };
// FIXME(Sa4dUs): use this global for constant offload sizes
cx.add_compiler_used_global(result.offload_sizes);
cx.offload_kernel_cache.borrow_mut().insert(symbol, result);
@ -532,8 +535,7 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>(
offload_dims: &OffloadKernelDims<'ll>,
) {
let cx = builder.cx;
let OffloadKernelGlobals { offload_sizes, offload_entry, memtransfer_types, region_id } =
offload_data;
let OffloadKernelGlobals { memtransfer_types, region_id, .. } = offload_data;
let OffloadKernelDims { num_workgroups, threads_per_block, workgroup_dims, thread_dims } =
offload_dims;
@ -548,20 +550,6 @@ pub(crate) fn gen_call_handling<'ll, 'tcx>(
let num_args = types.len() as u64;
let bb = builder.llbb();
// FIXME(Sa4dUs): dummy loads are a temp workaround, we should find a proper way to prevent these
// variables from being optimized away
for val in [offload_sizes, offload_entry] {
unsafe {
let dummy = llvm::LLVMBuildLoad2(
&builder.llbuilder,
llvm::LLVMTypeOf(val),
val,
b"dummy\0".as_ptr() as *const _,
);
llvm::LLVMSetVolatile(dummy, llvm::TRUE);
}
}
// Step 0)
unsafe {
llvm::LLVMRustPositionBuilderPastAllocas(&builder.llbuilder, builder.llfn());

View file

@ -131,7 +131,7 @@ fn emit_ptr_va_arg<'ll, 'tcx>(
);
if indirect {
let tmp_ret = bx.load(llty, addr, addr_align);
bx.load(bx.cx.layout_of(target_ty).llvm_type(bx.cx), tmp_ret, align.abi)
bx.load(layout.llvm_type(bx.cx), tmp_ret, align.abi)
} else {
bx.load(llty, addr, addr_align)
}
@ -1007,6 +1007,8 @@ fn emit_xtensa_va_arg<'ll, 'tcx>(
/// Determine the va_arg implementation to use. The LLVM va_arg instruction
/// is lacking in some instances, so we should only use it as a fallback.
///
/// <https://llvm.org/docs/LangRef.html#va-arg-instruction>
pub(super) fn emit_va_arg<'ll, 'tcx>(
bx: &mut Builder<'_, 'll, 'tcx>,
addr: OperandRef<'tcx, &'ll Value>,
@ -1015,6 +1017,10 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
let layout = bx.cx.layout_of(target_ty);
let target_ty_size = layout.layout.size().bytes();
// Some ABIs have special behavior for zero-sized types. currently `VaArgSafe` is not
// implemented for any zero-sized types, so this assert should always hold.
assert!(!bx.layout_of(target_ty).is_zst());
let target = &bx.cx.tcx.sess.target;
match target.arch {
Arch::X86 => emit_ptr_va_arg(
@ -1026,17 +1032,24 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes },
ForceRightAdjust::No,
),
Arch::AArch64 | Arch::Arm64EC if target.is_like_windows || target.is_like_darwin => {
emit_ptr_va_arg(
bx,
addr,
target_ty,
PassMode::Direct,
SlotSize::Bytes8,
if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes },
ForceRightAdjust::No,
)
}
Arch::Arm64EC => emit_ptr_va_arg(
bx,
addr,
target_ty,
PassMode::Direct,
SlotSize::Bytes8,
if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes },
ForceRightAdjust::No,
),
Arch::AArch64 if target.is_like_windows || target.is_like_darwin => emit_ptr_va_arg(
bx,
addr,
target_ty,
PassMode::Direct,
SlotSize::Bytes8,
if target.is_like_windows { AllowHigherAlign::No } else { AllowHigherAlign::Yes },
ForceRightAdjust::No,
),
Arch::AArch64 => emit_aapcs_va_arg(bx, addr, target_ty),
Arch::Arm => {
// Types wider than 16 bytes are not currently supported. Clang has special logic for
@ -1064,7 +1077,16 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
AllowHigherAlign::Yes,
ForceRightAdjust::Yes,
),
Arch::LoongArch32 => emit_ptr_va_arg(
Arch::RiscV32 if target.abi == Abi::Ilp32e => {
// FIXME: clang manually adjusts the alignment for this ABI. It notes:
//
// > To be compatible with GCC's behaviors, we force arguments with
// > 2×XLEN-bit alignment and size at most 2×XLEN bits like `long long`,
// > `unsigned long long` and `double` to have 4-byte alignment. This
// > behavior may be changed when RV32E/ILP32E is ratified.
bug!("c-variadic calls with ilp32e use a custom ABI and are not currently implemented");
}
Arch::RiscV32 | Arch::LoongArch32 => emit_ptr_va_arg(
bx,
addr,
target_ty,
@ -1073,7 +1095,7 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
AllowHigherAlign::Yes,
ForceRightAdjust::No,
),
Arch::LoongArch64 => emit_ptr_va_arg(
Arch::RiscV64 | Arch::LoongArch64 => emit_ptr_va_arg(
bx,
addr,
target_ty,
@ -1140,16 +1162,34 @@ pub(super) fn emit_va_arg<'ll, 'tcx>(
// This includes `target.is_like_darwin`, which on x86_64 targets is like sysv64.
Arch::X86_64 => emit_x86_64_sysv64_va_arg(bx, addr, target_ty),
Arch::Xtensa => emit_xtensa_va_arg(bx, addr, target_ty),
Arch::Hexagon => {
if target.env == Env::Musl {
emit_hexagon_va_arg_musl(bx, addr, target_ty)
} else {
emit_hexagon_va_arg_bare_metal(bx, addr, target_ty)
}
Arch::Hexagon => match target.env {
Env::Musl => emit_hexagon_va_arg_musl(bx, addr, target_ty),
_ => emit_hexagon_va_arg_bare_metal(bx, addr, target_ty),
},
Arch::Sparc64 => emit_ptr_va_arg(
bx,
addr,
target_ty,
if target_ty_size > 2 * 8 { PassMode::Indirect } else { PassMode::Direct },
SlotSize::Bytes8,
AllowHigherAlign::Yes,
ForceRightAdjust::No,
),
Arch::Bpf => bug!("bpf does not support c-variadic functions"),
Arch::SpirV => bug!("spirv does not support c-variadic functions"),
Arch::Mips | Arch::Mips32r6 | Arch::Mips64 | Arch::Mips64r6 => {
// FIXME: port MipsTargetLowering::lowerVAARG.
bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx))
}
Arch::Sparc | Arch::Avr | Arch::M68k | Arch::Msp430 => {
// Clang uses the LLVM implementation for these architectures.
bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx))
}
Arch::Other(_) => {
// For custom targets, use the LLVM va_arg instruction as a fallback.
bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx))
}
// For all other architecture/OS combinations fall back to using
// the LLVM va_arg instruction.
// https://llvm.org/docs/LangRef.html#va-arg-instruction
_ => bx.va_arg(addr.immediate(), bx.cx.layout_of(target_ty).llvm_type(bx.cx)),
}
}

View file

@ -18,7 +18,6 @@ rustc_ast = { path = "../rustc_ast" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_hashes = { path = "../rustc_hashes" }
rustc_hir = { path = "../rustc_hir" }

View file

@ -1,397 +0,0 @@
codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not implemented yet for L4Bender
codegen_ssa_aarch64_softfloat_neon = enabling the `neon` target feature on the current target is unsound due to ABI issues
codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error}
codegen_ssa_aix_strip_not_used = using host's `strip` binary to cross-compile to AIX which is not guaranteed to work
codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
codegen_ssa_binary_output_to_tty = option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty
codegen_ssa_bpf_staticlib_not_supported = linking static libraries is not supported for BPF
codegen_ssa_cgu_not_recorded =
CGU-reuse for `{$cgu_user_name}` is (mangled: `{$cgu_name}`) was not recorded
codegen_ssa_check_installed_visual_studio = please ensure that Visual Studio 2017 or later, or Build Tools for Visual Studio were installed with the Visual C++ option.
codegen_ssa_compiler_builtins_cannot_call =
`compiler_builtins` cannot call functions through upstream monomorphizations; encountered invalid call from `{$caller}` to `{$callee}`
codegen_ssa_copy_path = could not copy {$from} to {$to}: {$error}
codegen_ssa_copy_path_buf = unable to copy {$source_file} to {$output_path}: {$error}
codegen_ssa_cpu_required = target requires explicitly specifying a cpu with `-C target-cpu`
codegen_ssa_create_temp_dir = couldn't create a temp dir: {$error}
codegen_ssa_dlltool_fail_import_library =
dlltool could not create import library with {$dlltool_path} {$dlltool_args}:
{$stdout}
{$stderr}
codegen_ssa_dynamic_linking_with_lto =
cannot prefer dynamic linking when performing LTO
.note = only 'staticlib', 'bin', and 'cdylib' outputs are supported with LTO
codegen_ssa_error_calling_dlltool =
error calling dlltool '{$dlltool_path}': {$error}
codegen_ssa_error_creating_import_library =
error creating import library for {$lib_name}: {$error}
codegen_ssa_error_creating_remark_dir = failed to create remark directory: {$error}
codegen_ssa_error_writing_def_file =
error writing .DEF file: {$error}
codegen_ssa_extern_funcs_not_found = some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
codegen_ssa_extract_bundled_libs_archive_member = failed to get data from archive member '{$rlib}': {$error}
codegen_ssa_extract_bundled_libs_convert_name = failed to convert name '{$rlib}': {$error}
codegen_ssa_extract_bundled_libs_mmap_file = failed to mmap file '{$rlib}': {$error}
codegen_ssa_extract_bundled_libs_open_file = failed to open file '{$rlib}': {$error}
codegen_ssa_extract_bundled_libs_parse_archive = failed to parse archive '{$rlib}': {$error}
codegen_ssa_extract_bundled_libs_read_entry = failed to read entry '{$rlib}': {$error}
codegen_ssa_extract_bundled_libs_write_file = failed to write file '{$rlib}': {$error}
codegen_ssa_failed_to_get_layout = failed to get layout for {$ty}: {$err}
codegen_ssa_failed_to_write = failed to write {$path}: {$error}
codegen_ssa_feature_not_valid = the feature named `{$feature}` is not valid for this target
.label = `{$feature}` is not valid for this target
.help = consider removing the leading `+` in the feature name
codegen_ssa_field_associated_value_expected = associated value expected for `{$name}`
codegen_ssa_forbidden_ctarget_feature =
target feature `{$feature}` cannot be {$enabled} with `-Ctarget-feature`: {$reason}
.note = this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
codegen_ssa_forbidden_ctarget_feature_issue = for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
codegen_ssa_forbidden_target_feature_attr =
target feature `{$feature}` cannot be enabled with `#[target_feature]`: {$reason}
codegen_ssa_ignoring_emit_path = ignoring emit path because multiple .{$extension} files were produced
codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files were produced
codegen_ssa_incorrect_cgu_reuse_type =
CGU-reuse for `{$cgu_user_name}` is `{$actual_reuse}` but should be {$at_least ->
[one] {"at least "}
*[other] {""}
}`{$expected_reuse}`
codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.
codegen_ssa_invalid_monomorphization_basic_float_type = invalid monomorphization of `{$name}` intrinsic: expected basic float type, found `{$ty}`
codegen_ssa_invalid_monomorphization_basic_integer_or_ptr_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer or pointer type, found `{$ty}`
codegen_ssa_invalid_monomorphization_basic_integer_type = invalid monomorphization of `{$name}` intrinsic: expected basic integer type, found `{$ty}`
codegen_ssa_invalid_monomorphization_cannot_return = invalid monomorphization of `{$name}` intrinsic: cannot return `{$ret_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
codegen_ssa_invalid_monomorphization_cast_wide_pointer = invalid monomorphization of `{$name}` intrinsic: cannot cast wide pointer `{$ty}`
codegen_ssa_invalid_monomorphization_expected_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of second argument `{$second_arg}` to be a pointer to the element type `{$in_elem}` of the first argument `{$in_ty}`, found `{$expected_element}` != `{$mutability} {$in_elem}`
codegen_ssa_invalid_monomorphization_expected_pointer = invalid monomorphization of `{$name}` intrinsic: expected pointer, got `{$ty}`
codegen_ssa_invalid_monomorphization_expected_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_ty}`, found `{$ret_ty}`
codegen_ssa_invalid_monomorphization_expected_usize = invalid monomorphization of `{$name}` intrinsic: expected `usize`, got `{$ty}`
codegen_ssa_invalid_monomorphization_expected_vector_element_type = invalid monomorphization of `{$name}` intrinsic: expected element type `{$expected_element}` of vector type `{$vector_type}` to be a signed or unsigned integer type
codegen_ssa_invalid_monomorphization_float_to_int_unchecked = invalid monomorphization of `float_to_int_unchecked` intrinsic: expected basic float type, found `{$ty}`
codegen_ssa_invalid_monomorphization_floating_point_type = invalid monomorphization of `{$name}` intrinsic: `{$in_ty}` is not a floating-point type
codegen_ssa_invalid_monomorphization_floating_point_vector = invalid monomorphization of `{$name}` intrinsic: unsupported element type `{$f_ty}` of floating-point vector `{$in_ty}`
codegen_ssa_invalid_monomorphization_inserted_type = invalid monomorphization of `{$name}` intrinsic: expected inserted type `{$in_elem}` (element of input `{$in_ty}`), found `{$out_ty}`
codegen_ssa_invalid_monomorphization_invalid_bitmask = invalid monomorphization of `{$name}` intrinsic: invalid bitmask `{$mask_ty}`, expected `u{$expected_int_bits}` or `[u8; {$expected_bytes}]`
codegen_ssa_invalid_monomorphization_mask_wrong_element_type = invalid monomorphization of `{$name}` intrinsic: expected mask element type to be an integer, found `{$ty}`
codegen_ssa_invalid_monomorphization_mismatched_lengths = invalid monomorphization of `{$name}` intrinsic: mismatched lengths: mask length `{$m_len}` != other vector length `{$v_len}`
codegen_ssa_invalid_monomorphization_non_scalable_type = invalid monomorphization of `{$name}` intrinsic: expected non-scalable type, found scalable type `{$ty}`
codegen_ssa_invalid_monomorphization_return_element = invalid monomorphization of `{$name}` intrinsic: expected return element type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}` with element type `{$out_ty}`
codegen_ssa_invalid_monomorphization_return_integer_type = invalid monomorphization of `{$name}` intrinsic: expected return type with integer elements, found `{$ret_ty}` with non-integer `{$out_ty}`
codegen_ssa_invalid_monomorphization_return_length = invalid monomorphization of `{$name}` intrinsic: expected return type of length {$in_len}, found `{$ret_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_return_length_input_type = invalid monomorphization of `{$name}` intrinsic: expected return type with length {$in_len} (same as input type `{$in_ty}`), found `{$ret_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_return_type = invalid monomorphization of `{$name}` intrinsic: expected return type `{$in_elem}` (element of input `{$in_ty}`), found `{$ret_ty}`
codegen_ssa_invalid_monomorphization_second_argument_length = invalid monomorphization of `{$name}` intrinsic: expected second argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_simd_argument = invalid monomorphization of `{$name}` intrinsic: expected SIMD argument type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_first = invalid monomorphization of `{$name}` intrinsic: expected SIMD first type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_index_out_of_bounds = invalid monomorphization of `{$name}` intrinsic: SIMD index #{$arg_idx} is out of bounds (limit {$total_len})
codegen_ssa_invalid_monomorphization_simd_input = invalid monomorphization of `{$name}` intrinsic: expected SIMD input type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_return = invalid monomorphization of `{$name}` intrinsic: expected SIMD return type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_second = invalid monomorphization of `{$name}` intrinsic: expected SIMD second type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_simd_shuffle = invalid monomorphization of `{$name}` intrinsic: simd_shuffle index must be a SIMD vector of `u32`, got `{$ty}`
codegen_ssa_invalid_monomorphization_simd_third = invalid monomorphization of `{$name}` intrinsic: expected SIMD third type, found non-SIMD `{$ty}`
codegen_ssa_invalid_monomorphization_third_argument_length = invalid monomorphization of `{$name}` intrinsic: expected third argument with length {$in_len} (same as input type `{$in_ty}`), found `{$arg_ty}` with length {$out_len}
codegen_ssa_invalid_monomorphization_unrecognized_intrinsic = invalid monomorphization of `{$name}` intrinsic: unrecognized intrinsic `{$name}`
codegen_ssa_invalid_monomorphization_unsupported_cast = invalid monomorphization of `{$name}` intrinsic: unsupported cast from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}` with element `{$out_elem}`
codegen_ssa_invalid_monomorphization_unsupported_operation = invalid monomorphization of `{$name}` intrinsic: unsupported operation on `{$in_ty}` with element `{$in_elem}`
codegen_ssa_invalid_monomorphization_unsupported_symbol = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` to `{$ret_ty}`
codegen_ssa_invalid_monomorphization_unsupported_symbol_of_size = invalid monomorphization of `{$name}` intrinsic: unsupported {$symbol} from `{$in_ty}` with element `{$in_elem}` of size `{$size}` to `{$ret_ty}`
codegen_ssa_ld64_unimplemented_modifier = `as-needed` modifier not implemented yet for ld64
codegen_ssa_lib_def_write_failure = failed to write lib.def file: {$error}
codegen_ssa_link_exe_status_stack_buffer_overrun = 0xc0000409 is `STATUS_STACK_BUFFER_OVERRUN`
.abort_note = this may have been caused by a program abort and not a stack buffer overrun
.event_log_note = consider checking the Application Event Log for Windows Error Reporting events to see the fail fast error code
codegen_ssa_link_exe_unexpected_error = `link.exe` returned an unexpected error
codegen_ssa_link_script_unavailable = can only use link script when linking with GNU-like linker
codegen_ssa_link_script_write_failure = failed to write link script to {$path}: {$error}
codegen_ssa_linker_file_stem = couldn't extract file stem from specified linker
codegen_ssa_linker_not_found = linker `{$linker_path}` not found
.note = {$error}
codegen_ssa_linker_output = {$inner}
codegen_ssa_linker_unsupported_modifier = `as-needed` modifier not supported for current linker
codegen_ssa_linking_failed = linking with `{$linker_path}` failed: {$exit_status}
codegen_ssa_lto_disallowed = lto can only be run for executables, cdylibs and static library outputs
codegen_ssa_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdylib-lto`
codegen_ssa_lto_proc_macro = lto cannot be used for `proc-macro` crate type without `-Zdylib-lto`
codegen_ssa_malformed_cgu_name =
found malformed codegen unit name `{$user_path}`. codegen units names must always start with the name of the crate (`{$crate_name}` in this case).
codegen_ssa_missing_cpp_build_tool_component = or a necessary component may be missing from the "C++ build tools" workload
codegen_ssa_missing_features = add the missing features in a `target_feature` attribute
codegen_ssa_missing_query_depgraph =
found CGU-reuse attribute but `-Zquery-dep-graph` was not specified
codegen_ssa_msvc_missing_linker = the msvc targets depend on the msvc linker but `link.exe` was not found
codegen_ssa_multiple_external_func_decl = multiple declarations of external function `{$function}` from library `{$library_name}` have different calling conventions
codegen_ssa_multiple_main_functions = entry symbol `main` declared multiple times
.help = did you use `#[no_mangle]` on `fn main`? Use `#![no_main]` to suppress the usual Rust-generated entry point
codegen_ssa_no_field = no field `{$name}`
codegen_ssa_no_module_named =
no module named `{$user_path}` (mangled: {$cgu_name}). available modules: {$cgu_names}
codegen_ssa_no_natvis_directory = error enumerating natvis directory: {$error}
codegen_ssa_no_saved_object_file = cached cgu {$cgu_name} should have an object file, but doesn't
codegen_ssa_processing_dymutil_failed = processing debug info with `dsymutil` failed: {$status}
.note = {$output}
codegen_ssa_read_file = failed to read file: {$message}
codegen_ssa_repair_vs_build_tools = the Visual Studio build tools may need to be repaired using the Visual Studio installer
codegen_ssa_requires_rust_abi = `#[track_caller]` requires Rust ABI
codegen_ssa_rlib_archive_build_failure = failed to build archive from rlib at `{$path}`: {$error}
codegen_ssa_rlib_incompatible_dependency_formats = `{$ty1}` and `{$ty2}` do not have equivalent dependency formats (`{$list1}` vs `{$list2}`)
codegen_ssa_rlib_missing_format = could not find formats for rlibs
codegen_ssa_rlib_not_found = could not find rlib for: `{$crate_name}`
codegen_ssa_rlib_only_rmeta_found = could not find rlib for: `{$crate_name}`, found rmeta (metadata) file
codegen_ssa_select_cpp_build_tool_workload = in the Visual Studio installer, ensure the "C++ build tools" workload is selected
codegen_ssa_self_contained_linker_missing = the self-contained linker was requested, but it wasn't found in the target's sysroot, or in rustc's sysroot
codegen_ssa_shuffle_indices_evaluation = could not evaluate shuffle_indices at compile time
codegen_ssa_specify_libraries_to_link = use the `-l` flag to specify native libraries to link
codegen_ssa_static_library_native_artifacts = link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.
codegen_ssa_static_library_native_artifacts_to_file = native artifacts to link against have been written to {$path}. The order and any duplication can be significant on some platforms.
codegen_ssa_stripping_debug_info_failed = stripping debug info with `{$util}` failed: {$status}
.note = {$output}
codegen_ssa_symbol_file_write_failure = failed to write symbols file: {$error}
codegen_ssa_target_feature_disable_or_enable =
the target features {$features} must all be either enabled or disabled together
codegen_ssa_target_feature_safe_trait = `#[target_feature(..)]` cannot be applied to safe trait method
.label = cannot be applied to safe trait method
.label_def = not an `unsafe` function
codegen_ssa_thorin_decompress_data = failed to decompress compressed section
codegen_ssa_thorin_duplicate_unit = duplicate split compilation unit ({$unit})
codegen_ssa_thorin_empty_unit = unit {$unit} in input DWARF object with no data
codegen_ssa_thorin_gimli_read = {$error}
codegen_ssa_thorin_gimli_write = {$error}
codegen_ssa_thorin_incompatible_index_version = incompatible `{$section}` index version: found version {$actual}, expected version {$format}
codegen_ssa_thorin_invalid_input_kind = input is not an archive or elf object
codegen_ssa_thorin_io = {$error}
codegen_ssa_thorin_missing_dwo_name = missing path attribute to DWARF object ({$id})
codegen_ssa_thorin_missing_referenced_unit = unit {$unit} referenced by executable was not found
codegen_ssa_thorin_missing_required_section = input object missing required section `{$section}`
codegen_ssa_thorin_mixed_input_encodings = input objects have mixed encodings
codegen_ssa_thorin_multiple_debug_info_section = multiple `.debug_info.dwo` sections
codegen_ssa_thorin_multiple_debug_types_section = multiple `.debug_types.dwo` sections in a package
codegen_ssa_thorin_multiple_relocations = multiple relocations for section `{$section}` at offset {$offset}
codegen_ssa_thorin_no_compilation_units = input object has no compilation units
codegen_ssa_thorin_no_die = no top-level debugging information entry in compilation/type unit
codegen_ssa_thorin_not_output_object_created = no output object was created from inputs
codegen_ssa_thorin_not_split_unit = regular compilation unit in object (missing dwo identifier)
codegen_ssa_thorin_object_read = {$error}
codegen_ssa_thorin_object_write = {$error}
codegen_ssa_thorin_offset_at_index = read offset at index {$index} of `.debug_str_offsets.dwo` section
codegen_ssa_thorin_parse_archive_member = failed to parse archive member
codegen_ssa_thorin_parse_index = failed to parse `{$section}` index section
codegen_ssa_thorin_parse_input_archive_file = failed to parse input archive file
codegen_ssa_thorin_parse_input_file_kind = failed to parse input file kind
codegen_ssa_thorin_parse_input_object_file = failed to parse input object file
codegen_ssa_thorin_parse_unit = failed to parse unit
codegen_ssa_thorin_parse_unit_abbreviations = failed to parse unit abbreviations
codegen_ssa_thorin_parse_unit_attribute = failed to parse unit attribute
codegen_ssa_thorin_parse_unit_header = failed to parse unit header
codegen_ssa_thorin_read_input_failure = failed to read input file
codegen_ssa_thorin_relocation_with_invalid_symbol = relocation with invalid symbol for section `{$section}` at offset {$offset}
codegen_ssa_thorin_row_not_in_index = row {$row} found in index's hash table not present in index
codegen_ssa_thorin_section_not_in_row = section not found in unit's row in index
codegen_ssa_thorin_section_without_name = section without name at offset {$offset}
codegen_ssa_thorin_str_at_offset = read string at offset {$offset} of `.debug_str.dwo` section
codegen_ssa_thorin_top_level_die_not_unit = top-level debugging information entry is not a compilation/type unit
codegen_ssa_thorin_unit_not_in_index = unit {$unit} from input package is not in its index
codegen_ssa_thorin_unsupported_relocation = unsupported relocation for section {$section} at offset {$offset}
codegen_ssa_unable_to_exe_linker = could not exec the linker `{$linker_path}`
.note = {$error}
.command_note = {$command_formatted}
codegen_ssa_unable_to_run = unable to run `{$util}`: {$error}
codegen_ssa_unable_to_run_dsymutil = unable to run `dsymutil`: {$error}
codegen_ssa_unable_to_write_debugger_visualizer = unable to write debugger visualizer file `{$path}`: {$error}
codegen_ssa_unknown_archive_kind =
don't know how to build archive of type: {$kind}
codegen_ssa_unknown_ctarget_feature =
unknown and unstable feature specified for `-Ctarget-feature`: `{$feature}`
.note = it is still passed through to the codegen backend, but use of this feature might be unsound and the behavior of this feature can change in the future
.possible_feature = you might have meant: `{$rust_feature}`
.consider_filing_feature_request = consider filing a feature request
codegen_ssa_unknown_ctarget_feature_prefix =
unknown feature specified for `-Ctarget-feature`: `{$feature}`
.note = features must begin with a `+` to enable or `-` to disable it
codegen_ssa_unknown_reuse_kind = unknown cgu-reuse-kind `{$kind}` specified
codegen_ssa_unstable_ctarget_feature =
unstable feature specified for `-Ctarget-feature`: `{$feature}`
.note = this feature is not stably supported; its behavior can change in the future
codegen_ssa_unsupported_link_self_contained = option `-C link-self-contained` is not supported on this target
codegen_ssa_use_cargo_directive = use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)
codegen_ssa_version_script_write_failure = failed to write version script: {$error}
codegen_ssa_visual_studio_not_installed = you may need to install Visual Studio build tools with the "C++ build tools" workload
codegen_ssa_xcrun_about =
the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file
codegen_ssa_xcrun_command_line_tools_insufficient =
when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode
codegen_ssa_xcrun_failed_invoking = invoking `{$command_formatted}` to find {$sdk_name}.sdk failed: {$error}
codegen_ssa_xcrun_found_developer_dir = found active developer directory at "{$developer_dir}"
# `xcrun` already outputs a message about missing Xcode installation, so we only augment it with details about env vars.
codegen_ssa_xcrun_no_developer_dir =
pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable
codegen_ssa_xcrun_sdk_path_warning = output of `xcrun` while finding {$sdk_name}.sdk
.note = {$stderr}
codegen_ssa_xcrun_unsuccessful = failed running `{$command_formatted}` to find {$sdk_name}.sdk
.note = {$stdout}{$stderr}

View file

@ -3,6 +3,7 @@ use std::path::PathBuf;
use std::process::Command;
use itertools::Itertools;
use rustc_errors::inline_fluent;
use rustc_middle::middle::exported_symbols::SymbolExportKind;
use rustc_session::Session;
pub(super) use rustc_target::spec::apple::OSVersion;
@ -10,7 +11,6 @@ use rustc_target::spec::{Arch, Env, Os, Target};
use tracing::debug;
use crate::errors::{XcrunError, XcrunSdkPathWarning};
use crate::fluent_generated as fluent;
#[cfg(test)]
mod tests;
@ -185,19 +185,21 @@ pub(super) fn get_sdk_root(sess: &Session) -> Option<PathBuf> {
// FIXME(madsmtm): Make this a lint, to allow deny warnings to work.
// (Or fix <https://github.com/rust-lang/rust/issues/21204>).
let mut diag = sess.dcx().create_warn(err);
diag.note(fluent::codegen_ssa_xcrun_about);
diag.note(inline_fluent!("the SDK is needed by the linker to know where to find symbols in system libraries and for embedding the SDK version in the final object file"));
// Recognize common error cases, and give more Rust-specific error messages for those.
if let Some(developer_dir) = xcode_select_developer_dir() {
diag.arg("developer_dir", &developer_dir);
diag.note(fluent::codegen_ssa_xcrun_found_developer_dir);
diag.note(inline_fluent!(
"found active developer directory at \"{$developer_dir}\""
));
if developer_dir.as_os_str().to_string_lossy().contains("CommandLineTools") {
if sdk_name != "MacOSX" {
diag.help(fluent::codegen_ssa_xcrun_command_line_tools_insufficient);
diag.help(inline_fluent!("when compiling for iOS, tvOS, visionOS or watchOS, you need a full installation of Xcode"));
}
}
} else {
diag.help(fluent::codegen_ssa_xcrun_no_developer_dir);
diag.help(inline_fluent!("pass the path of an Xcode installation via the DEVELOPER_DIR environment variable, or an SDK with the SDKROOT environment variable"));
}
diag.emit();

View file

@ -663,7 +663,7 @@ fn link_dwarf_object(sess: &Session, cg_results: &CodegenResults, executable_out
}
#[derive(LintDiagnostic)]
#[diag(codegen_ssa_linker_output)]
#[diag("{$inner}")]
/// Translating this is kind of useless. We don't pass translation flags to the linker, so we'd just
/// end up with inconsistent languages within the same diagnostic.
struct LinkerOutput {

File diff suppressed because it is too large Load diff

View file

@ -55,8 +55,6 @@ pub mod size_of_val;
pub mod target_features;
pub mod traits;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub struct ModuleCodegen<M> {
/// The name of the module. When the crate may be saved between
/// compilations, incremental compilation requires that name be

View file

@ -995,12 +995,14 @@ cfg_select! {
}
unix => {
pub fn get_resident_set_size() -> Option<usize> {
use libc::{sysconf, _SC_PAGESIZE};
let field = 1;
let contents = fs::read("/proc/self/statm").ok()?;
let contents = String::from_utf8(contents).ok()?;
let s = contents.split_whitespace().nth(field)?;
let npages = s.parse::<usize>().ok()?;
Some(npages * 4096)
// SAFETY: `sysconf(_SC_PAGESIZE)` has no side effects and is safe to call.
Some(npages * unsafe { sysconf(_SC_PAGESIZE) } as usize)
}
}
_ => {

View file

@ -9,11 +9,8 @@ anstyle = "1.0.13"
jiff = { version = "0.2.5", default-features = false, features = ["std"] }
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_const_eval = { path = "../rustc_const_eval" }
rustc_data_structures = { path = "../rustc_data_structures" }
@ -22,7 +19,6 @@ rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
rustc_hir_analysis = { path = "../rustc_hir_analysis" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }
rustc_hir_typeck = { path = "../rustc_hir_typeck" }
rustc_index = { path = "../rustc_index" }
rustc_interface = { path = "../rustc_interface" }
rustc_lexer = { path = "../rustc_lexer" }
@ -35,7 +31,6 @@ rustc_mir_build = { path = "../rustc_mir_build" }
rustc_mir_transform = { path = "../rustc_mir_transform" }
rustc_parse = { path = "../rustc_parse" }
rustc_passes = { path = "../rustc_passes" }
rustc_pattern_analysis = { path = "../rustc_pattern_analysis" }
rustc_public = { path = "../rustc_public", features = ["rustc_internal"] }
rustc_resolve = { path = "../rustc_resolve" }
rustc_session = { path = "../rustc_session" }

View file

@ -20,7 +20,7 @@ use std::fs::{self, File};
use std::io::{self, IsTerminal, Read, Write};
use std::panic::{self, PanicHookInfo};
use std::path::{Path, PathBuf};
use std::process::{self, Command, Stdio};
use std::process::{Command, ExitCode, Stdio, Termination};
use std::sync::OnceLock;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Instant;
@ -114,25 +114,13 @@ pub fn default_translator() -> Translator {
pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
// tidy-alphabetical-start
rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE,
rustc_ast_passes::DEFAULT_LOCALE_RESOURCE,
rustc_borrowck::DEFAULT_LOCALE_RESOURCE,
rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE,
rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE,
rustc_const_eval::DEFAULT_LOCALE_RESOURCE,
rustc_errors::DEFAULT_LOCALE_RESOURCE,
rustc_expand::DEFAULT_LOCALE_RESOURCE,
rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE,
rustc_hir_typeck::DEFAULT_LOCALE_RESOURCE,
rustc_lint::DEFAULT_LOCALE_RESOURCE,
rustc_metadata::DEFAULT_LOCALE_RESOURCE,
rustc_middle::DEFAULT_LOCALE_RESOURCE,
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
rustc_mir_transform::DEFAULT_LOCALE_RESOURCE,
rustc_parse::DEFAULT_LOCALE_RESOURCE,
rustc_passes::DEFAULT_LOCALE_RESOURCE,
rustc_pattern_analysis::DEFAULT_LOCALE_RESOURCE,
rustc_resolve::DEFAULT_LOCALE_RESOURCE,
rustc_trait_selection::DEFAULT_LOCALE_RESOURCE,
// tidy-alphabetical-end
];
@ -1404,10 +1392,10 @@ fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
/// Variant of `catch_fatal_errors` for the `interface::Result` return type
/// that also computes the exit code.
pub fn catch_with_exit_code(f: impl FnOnce()) -> i32 {
pub fn catch_with_exit_code<T: Termination>(f: impl FnOnce() -> T) -> ExitCode {
match catch_fatal_errors(f) {
Ok(()) => EXIT_SUCCESS,
_ => EXIT_FAILURE,
Ok(status) => status.report(),
_ => ExitCode::FAILURE,
}
}
@ -1692,7 +1680,7 @@ pub fn install_ctrlc_handler() {
.expect("Unable to install ctrlc handler");
}
pub fn main() -> ! {
pub fn main() -> ExitCode {
let start_time = Instant::now();
let start_rss = get_resident_set_size();
@ -1712,5 +1700,5 @@ pub fn main() -> ! {
print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss, format);
}
process::exit(exit_code)
exit_code
}

View file

@ -14,7 +14,6 @@ rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_codes = { path = "../rustc_error_codes" }
rustc_error_messages = { path = "../rustc_error_messages" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hashes = { path = "../rustc_hashes" }
rustc_index = { path = "../rustc_index" }
rustc_lint_defs = { path = "../rustc_lint_defs" }

View file

@ -1,48 +0,0 @@
errors_delayed_at_with_newline =
delayed at {$emitted_at}
{$note}
errors_delayed_at_without_newline =
delayed at {$emitted_at} - {$note}
errors_expected_lifetime_parameter =
expected lifetime {$count ->
[1] parameter
*[other] parameters
}
errors_indicate_anonymous_lifetime =
indicate the anonymous {$count ->
[1] lifetime
*[other] lifetimes
}
errors_invalid_flushed_delayed_diagnostic_level =
`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`
errors_target_inconsistent_architecture =
inconsistent target specification: "data-layout" claims architecture is {$dl}-endian, while "target-endian" is `{$target}`
errors_target_inconsistent_pointer_width =
inconsistent target specification: "data-layout" claims pointers are {$pointer_size}-bit, while "target-pointer-width" is `{$target}`
errors_target_invalid_address_space =
invalid address space `{$addr_space}` for `{$cause}` in "data-layout": {$err}
errors_target_invalid_alignment =
invalid alignment for `{$cause}` in "data-layout": `{$align}` is {$err_kind ->
[not_power_of_two] not a power of 2
[too_large] too large
*[other] {""}
}
errors_target_invalid_bits =
invalid {$kind} `{$bit}` for `{$cause}` in "data-layout": {$err}
errors_target_invalid_bits_size = {$err}
errors_target_invalid_datalayout_pointer_spec =
unknown pointer specification `{$err}` in datalayout string
errors_target_missing_alignment =
missing alignment for `{$cause}` in "data-layout"

View file

@ -7,8 +7,7 @@ use rustc_span::{Span, Symbol};
use crate::diagnostic::DiagLocation;
use crate::{
Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic,
fluent_generated as fluent,
Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, Subdiagnostic, inline_fluent,
};
impl IntoDiagArg for DiagLocation {
@ -44,43 +43,48 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for TargetDataLayoutErrors<'_> {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
match self {
TargetDataLayoutErrors::InvalidAddressSpace { addr_space, err, cause } => {
Diag::new(dcx, level, fluent::errors_target_invalid_address_space)
Diag::new(dcx, level, inline_fluent!("invalid address space `{$addr_space}` for `{$cause}` in \"data-layout\": {$err}"))
.with_arg("addr_space", addr_space)
.with_arg("cause", cause)
.with_arg("err", err)
}
TargetDataLayoutErrors::InvalidBits { kind, bit, cause, err } => {
Diag::new(dcx, level, fluent::errors_target_invalid_bits)
Diag::new(dcx, level, inline_fluent!("invalid {$kind} `{$bit}` for `{$cause}` in \"data-layout\": {$err}"))
.with_arg("kind", kind)
.with_arg("bit", bit)
.with_arg("cause", cause)
.with_arg("err", err)
}
TargetDataLayoutErrors::MissingAlignment { cause } => {
Diag::new(dcx, level, fluent::errors_target_missing_alignment)
Diag::new(dcx, level, inline_fluent!("missing alignment for `{$cause}` in \"data-layout\""))
.with_arg("cause", cause)
}
TargetDataLayoutErrors::InvalidAlignment { cause, err } => {
Diag::new(dcx, level, fluent::errors_target_invalid_alignment)
.with_arg("cause", cause)
.with_arg("err_kind", err.diag_ident())
.with_arg("align", err.align())
Diag::new(dcx, level, inline_fluent!("invalid alignment for `{$cause}` in \"data-layout\": `{$align}` is {$err_kind ->
[not_power_of_two] not a power of 2
[too_large] too large
*[other] {\"\"}
}"))
.with_arg("cause", cause)
.with_arg("err_kind", err.diag_ident())
.with_arg("align", err.align())
}
TargetDataLayoutErrors::InconsistentTargetArchitecture { dl, target } => {
Diag::new(dcx, level, fluent::errors_target_inconsistent_architecture)
.with_arg("dl", dl)
.with_arg("target", target)
Diag::new(dcx, level, inline_fluent!(
"inconsistent target specification: \"data-layout\" claims architecture is {$dl}-endian, while \"target-endian\" is `{$target}`"
))
.with_arg("dl", dl).with_arg("target", target)
}
TargetDataLayoutErrors::InconsistentTargetPointerWidth { pointer_size, target } => {
Diag::new(dcx, level, fluent::errors_target_inconsistent_pointer_width)
.with_arg("pointer_size", pointer_size)
.with_arg("target", target)
Diag::new(dcx, level, inline_fluent!(
"inconsistent target specification: \"data-layout\" claims pointers are {$pointer_size}-bit, while \"target-pointer-width\" is `{$target}`"
)).with_arg("pointer_size", pointer_size).with_arg("target", target)
}
TargetDataLayoutErrors::InvalidBitsSize { err } => {
Diag::new(dcx, level, fluent::errors_target_invalid_bits_size).with_arg("err", err)
Diag::new(dcx, level, inline_fluent!("{$err}")).with_arg("err", err)
}
TargetDataLayoutErrors::UnknownPointerSpecification { err } => {
Diag::new(dcx, level, fluent::errors_target_invalid_datalayout_pointer_spec)
Diag::new(dcx, level, inline_fluent!("unknown pointer specification `{$err}` in datalayout string"))
.with_arg("err", err)
}
}
@ -99,7 +103,12 @@ impl Subdiagnostic for SingleLabelManySpans {
}
#[derive(Subdiagnostic)]
#[label(errors_expected_lifetime_parameter)]
#[label(
"expected lifetime {$count ->
[1] parameter
*[other] parameters
}"
)]
pub struct ExpectedLifetimeParameter {
#[primary_span]
pub span: Span,
@ -107,7 +116,14 @@ pub struct ExpectedLifetimeParameter {
}
#[derive(Subdiagnostic)]
#[suggestion(errors_indicate_anonymous_lifetime, code = "{suggestion}", style = "verbose")]
#[suggestion(
"indicate the anonymous {$count ->
[1] lifetime
*[other] lifetimes
}",
code = "{suggestion}",
style = "verbose"
)]
pub struct IndicateAnonymousLifetime {
#[primary_span]
pub span: Span,

View file

@ -45,8 +45,7 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) {
rustc_span::create_default_session_globals_then(|| {
let sm = Arc::new(SourceMap::new(FilePathMapping::empty()));
sm.new_source_file(filename(&sm, "test.rs"), code.to_owned());
let translator =
Translator::with_fallback_bundle(vec![crate::DEFAULT_LOCALE_RESOURCE], false);
let translator = Translator::with_fallback_bundle(vec![], false);
let output = Arc::new(Mutex::new(Vec::new()));
let je = JsonEmitter::new(

View file

@ -92,8 +92,6 @@ pub mod translation;
pub type PResult<'a, T> = Result<T, Diag<'a>>;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
#[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(PResult<'_, ()>, 24);
@ -1531,7 +1529,9 @@ impl DiagCtxtInner {
// the usual `Diag`/`DiagCtxt` level, so we must augment `bug`
// in a lower-level fashion.
bug.arg("level", bug.level);
let msg = crate::fluent_generated::errors_invalid_flushed_delayed_diagnostic_level;
let msg = inline_fluent!(
"`flushed_delayed` got diagnostic with level {$level}, instead of the expected `DelayedBug`"
);
let msg = self.eagerly_translate_for_subdiag(&bug, msg); // after the `arg` call
bug.sub(Note, msg, bug.span.primary_span().unwrap().into());
}
@ -1573,10 +1573,13 @@ impl DelayedDiagInner {
// lower-level fashion.
let mut diag = self.inner;
let msg = match self.note.status() {
BacktraceStatus::Captured => crate::fluent_generated::errors_delayed_at_with_newline,
BacktraceStatus::Captured => inline_fluent!(
"delayed at {$emitted_at}
{$note}"
),
// Avoid the needless newline when no backtrace has been captured,
// the display impl should just be a single line.
_ => crate::fluent_generated::errors_delayed_at_without_newline,
_ => inline_fluent!("delayed at {$emitted_at} - {$note}"),
};
diag.arg("emitted_at", diag.emitted_at.clone());
diag.arg("note", self.note);

View file

@ -16,7 +16,6 @@ rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_lint_defs = { path = "../rustc_lint_defs" }

View file

@ -1,207 +0,0 @@
expand_attributes_on_expressions_experimental =
attributes on expressions are experimental
.help_outer_doc = `///` is used for outer documentation comments; for a plain comment, use `//`
.help_inner_doc = `//!` is used for inner documentation comments; for a plain comment, use `//` by removing the `!` or inserting a space in between them: `// !`
expand_cfg_attr_no_attributes = `#[cfg_attr]` does not expand to any attributes
expand_count_repetition_misplaced =
`count` can not be placed inside the innermost repetition
expand_crate_name_in_cfg_attr =
`crate_name` within an `#![cfg_attr]` attribute is forbidden
expand_crate_type_in_cfg_attr =
`crate_type` within an `#![cfg_attr]` attribute is forbidden
expand_custom_attribute_panicked =
custom attribute panicked
.help = message: {$message}
expand_duplicate_matcher_binding = duplicate matcher binding
.label = duplicate binding
.label2 = previous binding
expand_empty_delegation_mac =
empty {$kind} delegation is not supported
expand_expected_paren_or_brace =
expected `(` or `{"{"}`, found `{$token}`
expand_explain_doc_comment_inner =
inner doc comments expand to `#![doc = "..."]`, which is what this macro attempted to match
expand_explain_doc_comment_outer =
outer doc comments expand to `#[doc = "..."]`, which is what this macro attempted to match
expand_expr_repeat_no_syntax_vars =
attempted to repeat an expression containing no syntax variables matched as repeating at this depth
expand_feature_not_allowed =
the feature `{$name}` is not in the list of allowed features
expand_feature_removed =
feature has been removed
.label = feature has been removed
.note = removed in {$removed_rustc_version}{$pull_note}
.reason = {$reason}
expand_file_modules_in_proc_macro_input_are_unstable =
file modules in proc macro input are unstable
expand_glob_delegation_outside_impls =
glob delegation is only supported in impls
expand_glob_delegation_traitless_qpath =
qualified path without a trait in glob delegation
expand_incomplete_parse =
macro expansion ignores {$descr} and any tokens following
.label = caused by the macro expansion here
.note = the usage of `{$macro_path}!` is likely invalid in {$kind_name} context
.suggestion_add_semi = you might be missing a semicolon here
expand_invalid_cfg_expected_syntax = expected syntax is
expand_invalid_cfg_multiple_predicates = multiple `cfg` predicates are specified
expand_invalid_cfg_no_parens = `cfg` is not followed by parentheses
expand_invalid_cfg_no_predicate = `cfg` predicate is not specified
expand_invalid_cfg_predicate_literal = `cfg` predicate key cannot be a literal
expand_invalid_fragment_specifier =
invalid fragment specifier `{$fragment}`
.help = {$help}
expand_macro_args_bad_delim = `{$rule_kw}` rule argument matchers require parentheses
expand_macro_args_bad_delim_sugg = the delimiters should be `(` and `)`
expand_macro_body_stability =
macros cannot have body stability attributes
.label = invalid body stability attribute
.label2 = body stability attribute affects this macro
expand_macro_call_unused_doc_comment = unused doc comment
.label = rustdoc does not generate documentation for macro invocations
.help = to document an item produced by a macro, the macro must produce the documentation as part of its expansion
expand_macro_const_stability =
macros cannot have const stability attributes
.label = invalid const stability attribute
.label2 = const stability attribute affects this macro
expand_macro_expands_to_match_arm = macros cannot expand to match arms
expand_malformed_feature_attribute =
malformed `feature` attribute input
.expected = expected just one word
expand_meta_var_dif_seq_matchers = {$msg}
expand_metavar_still_repeating = variable `{$ident}` is still repeating at this depth
.label = expected repetition
expand_metavariable_wrong_operator = meta-variable repeats with different Kleene operator
.binder_label = expected repetition
.occurrence_label = conflicting repetition
expand_missing_fragment_specifier = missing fragment specifier
.note = fragment specifiers must be provided
.suggestion_add_fragspec = try adding a specifier here
.valid = {$valid}
expand_module_circular =
circular modules: {$modules}
expand_module_file_not_found =
file not found for module `{$name}`
.help = to create the module `{$name}`, create file "{$default_path}" or "{$secondary_path}"
.note = if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead
expand_module_in_block =
cannot declare a file module inside a block unless it has a path attribute
.help = maybe `use` the module `{$name}` instead of redeclaring it
.note = file modules are usually placed outside of blocks, at the top level of the file
expand_module_multiple_candidates =
file for module `{$name}` found at both "{$default_path}" and "{$secondary_path}"
.help = delete or rename one of them to remove the ambiguity
expand_must_repeat_once =
this must repeat at least once
expand_mve_extra_tokens =
unexpected trailing tokens
.label = for this metavariable expression
.range = the `{$name}` metavariable expression takes between {$min_or_exact_args} and {$max_args} arguments
.exact = the `{$name}` metavariable expression takes {$min_or_exact_args ->
[zero] no arguments
[one] a single argument
*[other] {$min_or_exact_args} arguments
}
.suggestion = try removing {$extra_count ->
[one] this token
*[other] these tokens
}
expand_mve_missing_paren =
expected `(`
.label = for this this metavariable expression
.unexpected = unexpected token
.note = metavariable expressions use function-like parentheses syntax
.suggestion = try adding parentheses
expand_mve_unrecognized_expr =
unrecognized metavariable expression
.label = not a valid metavariable expression
.note = valid metavariable expressions are {$valid_expr_list}
expand_mve_unrecognized_var =
variable `{$key}` is not recognized in meta-variable expression
expand_or_patterns_back_compat = the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
.suggestion = use pat_param to preserve semantics
expand_proc_macro_back_compat = using an old version of `{$crate_name}`
.note = older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives
expand_proc_macro_derive_panicked =
proc-macro derive panicked
.help = message: {$message}
expand_proc_macro_derive_tokens =
proc-macro derive produced unparsable tokens
expand_proc_macro_panicked =
proc macro panicked
.help = message: {$message}
expand_recursion_limit_reached =
recursion limit reached while expanding `{$descr}`
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
expand_remove_expr_not_supported =
removing an expression is not supported in this position
expand_remove_node_not_supported =
removing {$descr} is not supported in this position
expand_resolve_relative_path =
cannot resolve relative path in non-file source `{$path}`
expand_trace_macro = trace_macro
expand_trailing_semi_macro = trailing semicolon in macro used in expression position
.note1 = macro invocations at the end of a block are treated as expressions
.note2 = to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}`
expand_unknown_macro_variable = unknown macro variable `{$name}`
expand_unsupported_key_value =
key-value macro attributes are not supported
expand_unused_builtin_attribute = unused attribute `{$attr_name}`
.note = the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`
.suggestion = remove the attribute
expand_wrong_fragment_kind =
non-{$kind} macro in {$kind} position: {$name}

View file

@ -15,6 +15,7 @@ use rustc_attr_parsing::{
AttributeParser, CFG_TEMPLATE, EvalConfigResult, ShouldEmit, eval_config_entry, parse_cfg,
};
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_errors::inline_fluent;
use rustc_feature::{
ACCEPTED_LANG_FEATURES, EnabledLangFeature, EnabledLibFeature, Features, REMOVED_LANG_FEATURES,
UNSTABLE_LANG_FEATURES,
@ -432,14 +433,14 @@ impl<'a> StripUnconfigured<'a> {
&self.sess,
sym::stmt_expr_attributes,
attr.span,
crate::fluent_generated::expand_attributes_on_expressions_experimental,
inline_fluent!("attributes on expressions are experimental"),
);
if attr.is_doc_comment() {
err.help(if attr.style == AttrStyle::Outer {
crate::fluent_generated::expand_help_outer_doc
inline_fluent!("`///` is used for outer documentation comments; for a plain comment, use `//`")
} else {
crate::fluent_generated::expand_help_inner_doc
inline_fluent!("`//!` is used for inner documentation comments; for a plain comment, use `//` by removing the `!` or inserting a space in between them: `// !`")
});
}

View file

@ -7,32 +7,34 @@ use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol};
#[derive(LintDiagnostic)]
#[diag(expand_cfg_attr_no_attributes)]
#[diag("`#[cfg_attr]` does not expand to any attributes")]
pub(crate) struct CfgAttrNoAttributes;
#[derive(Diagnostic)]
#[diag(expand_expr_repeat_no_syntax_vars)]
#[diag(
"attempted to repeat an expression containing no syntax variables matched as repeating at this depth"
)]
pub(crate) struct NoSyntaxVarsExprRepeat {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_must_repeat_once)]
#[diag("this must repeat at least once")]
pub(crate) struct MustRepeatOnce {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_count_repetition_misplaced)]
#[diag("`count` can not be placed inside the innermost repetition")]
pub(crate) struct CountRepetitionMisplaced {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_metavar_still_repeating)]
#[diag("variable `{$ident}` is still repeating at this depth")]
pub(crate) struct MacroVarStillRepeating {
#[primary_span]
pub span: Span,
@ -40,24 +42,24 @@ pub(crate) struct MacroVarStillRepeating {
}
#[derive(LintDiagnostic)]
#[diag(expand_metavar_still_repeating)]
#[diag("variable `{$ident}` is still repeating at this depth")]
pub(crate) struct MetaVarStillRepeatingLint {
#[label]
#[label("expected repetition")]
pub label: Span,
pub ident: MacroRulesNormalizedIdent,
}
#[derive(LintDiagnostic)]
#[diag(expand_metavariable_wrong_operator)]
#[diag("meta-variable repeats with different Kleene operator")]
pub(crate) struct MetaVariableWrongOperator {
#[label(expand_binder_label)]
#[label("expected repetition")]
pub binder: Span,
#[label(expand_occurrence_label)]
#[label("conflicting repetition")]
pub occurrence: Span,
}
#[derive(Diagnostic)]
#[diag(expand_meta_var_dif_seq_matchers)]
#[diag("{$msg}")]
pub(crate) struct MetaVarsDifSeqMatchers {
#[primary_span]
pub span: Span,
@ -65,13 +67,13 @@ pub(crate) struct MetaVarsDifSeqMatchers {
}
#[derive(LintDiagnostic)]
#[diag(expand_unknown_macro_variable)]
#[diag("unknown macro variable `{$name}`")]
pub(crate) struct UnknownMacroVariable {
pub name: MacroRulesNormalizedIdent,
}
#[derive(Diagnostic)]
#[diag(expand_resolve_relative_path)]
#[diag("cannot resolve relative path in non-file source `{$path}`")]
pub(crate) struct ResolveRelativePath {
#[primary_span]
pub span: Span,
@ -79,31 +81,31 @@ pub(crate) struct ResolveRelativePath {
}
#[derive(Diagnostic)]
#[diag(expand_macro_const_stability)]
#[diag("macros cannot have const stability attributes")]
pub(crate) struct MacroConstStability {
#[primary_span]
#[label]
#[label("invalid const stability attribute")]
pub span: Span,
#[label(expand_label2)]
#[label("const stability attribute affects this macro")]
pub head_span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_macro_body_stability)]
#[diag("macros cannot have body stability attributes")]
pub(crate) struct MacroBodyStability {
#[primary_span]
#[label]
#[label("invalid body stability attribute")]
pub span: Span,
#[label(expand_label2)]
#[label("body stability attribute affects this macro")]
pub head_span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_feature_removed, code = E0557)]
#[note]
#[diag("feature has been removed", code = E0557)]
#[note("removed in {$removed_rustc_version}{$pull_note}")]
pub(crate) struct FeatureRemoved<'a> {
#[primary_span]
#[label]
#[label("feature has been removed")]
pub span: Span,
#[subdiagnostic]
pub reason: Option<FeatureRemovedReason<'a>>,
@ -112,13 +114,13 @@ pub(crate) struct FeatureRemoved<'a> {
}
#[derive(Subdiagnostic)]
#[note(expand_reason)]
#[note("{$reason}")]
pub(crate) struct FeatureRemovedReason<'a> {
pub reason: &'a str,
}
#[derive(Diagnostic)]
#[diag(expand_feature_not_allowed, code = E0725)]
#[diag("the feature `{$name}` is not in the list of allowed features", code = E0725)]
pub(crate) struct FeatureNotAllowed {
#[primary_span]
pub span: Span,
@ -126,8 +128,10 @@ pub(crate) struct FeatureNotAllowed {
}
#[derive(Diagnostic)]
#[diag(expand_recursion_limit_reached)]
#[help]
#[diag("recursion limit reached while expanding `{$descr}`")]
#[help(
"consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]` attribute to your crate (`{$crate_name}`)"
)]
pub(crate) struct RecursionLimitReached {
#[primary_span]
pub span: Span,
@ -137,7 +141,7 @@ pub(crate) struct RecursionLimitReached {
}
#[derive(Diagnostic)]
#[diag(expand_malformed_feature_attribute, code = E0556)]
#[diag("malformed `feature` attribute input", code = E0556)]
pub(crate) struct MalformedFeatureAttribute {
#[primary_span]
pub span: Span,
@ -147,12 +151,16 @@ pub(crate) struct MalformedFeatureAttribute {
#[derive(Subdiagnostic)]
pub(crate) enum MalformedFeatureAttributeHelp {
#[label(expand_expected)]
#[label("expected just one word")]
Label {
#[primary_span]
span: Span,
},
#[suggestion(expand_expected, code = "{suggestion}", applicability = "maybe-incorrect")]
#[suggestion(
"expected just one word",
code = "{suggestion}",
applicability = "maybe-incorrect"
)]
Suggestion {
#[primary_span]
span: Span,
@ -161,7 +169,7 @@ pub(crate) enum MalformedFeatureAttributeHelp {
}
#[derive(Diagnostic)]
#[diag(expand_remove_expr_not_supported)]
#[diag("removing an expression is not supported in this position")]
pub(crate) struct RemoveExprNotSupported {
#[primary_span]
pub span: Span,
@ -169,32 +177,32 @@ pub(crate) struct RemoveExprNotSupported {
#[derive(Diagnostic)]
pub(crate) enum InvalidCfg {
#[diag(expand_invalid_cfg_no_parens)]
#[diag("`cfg` is not followed by parentheses")]
NotFollowedByParens {
#[primary_span]
#[suggestion(
expand_invalid_cfg_expected_syntax,
"expected syntax is",
code = "cfg(/* predicate */)",
applicability = "has-placeholders"
)]
span: Span,
},
#[diag(expand_invalid_cfg_no_predicate)]
#[diag("`cfg` predicate is not specified")]
NoPredicate {
#[primary_span]
#[suggestion(
expand_invalid_cfg_expected_syntax,
"expected syntax is",
code = "cfg(/* predicate */)",
applicability = "has-placeholders"
)]
span: Span,
},
#[diag(expand_invalid_cfg_multiple_predicates)]
#[diag("multiple `cfg` predicates are specified")]
MultiplePredicates {
#[primary_span]
span: Span,
},
#[diag(expand_invalid_cfg_predicate_literal)]
#[diag("`cfg` predicate key cannot be a literal")]
PredicateLiteral {
#[primary_span]
span: Span,
@ -202,7 +210,7 @@ pub(crate) enum InvalidCfg {
}
#[derive(Diagnostic)]
#[diag(expand_wrong_fragment_kind)]
#[diag("non-{$kind} macro in {$kind} position: {$name}")]
pub(crate) struct WrongFragmentKind<'a> {
#[primary_span]
pub span: Span,
@ -211,28 +219,28 @@ pub(crate) struct WrongFragmentKind<'a> {
}
#[derive(Diagnostic)]
#[diag(expand_unsupported_key_value)]
#[diag("key-value macro attributes are not supported")]
pub(crate) struct UnsupportedKeyValue {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_incomplete_parse)]
#[note]
#[diag("macro expansion ignores {$descr} and any tokens following")]
#[note("the usage of `{$macro_path}!` is likely invalid in {$kind_name} context")]
pub(crate) struct IncompleteParse<'a> {
#[primary_span]
pub span: Span,
pub descr: String,
#[label]
#[label("caused by the macro expansion here")]
pub label_span: Span,
pub macro_path: &'a ast::Path,
pub kind_name: &'a str,
#[note(expand_macro_expands_to_match_arm)]
#[note("macros cannot expand to match arms")]
pub expands_to_match_arm: bool,
#[suggestion(
expand_suggestion_add_semi,
"you might be missing a semicolon here",
style = "verbose",
code = ";",
applicability = "maybe-incorrect"
@ -241,7 +249,7 @@ pub(crate) struct IncompleteParse<'a> {
}
#[derive(Diagnostic)]
#[diag(expand_remove_node_not_supported)]
#[diag("removing {$descr} is not supported in this position")]
pub(crate) struct RemoveNodeNotSupported {
#[primary_span]
pub span: Span,
@ -249,7 +257,7 @@ pub(crate) struct RemoveNodeNotSupported {
}
#[derive(Diagnostic)]
#[diag(expand_module_circular)]
#[diag("circular modules: {$modules}")]
pub(crate) struct ModuleCircular {
#[primary_span]
pub span: Span,
@ -257,8 +265,8 @@ pub(crate) struct ModuleCircular {
}
#[derive(Diagnostic)]
#[diag(expand_module_in_block)]
#[note]
#[diag("cannot declare a file module inside a block unless it has a path attribute")]
#[note("file modules are usually placed outside of blocks, at the top level of the file")]
pub(crate) struct ModuleInBlock {
#[primary_span]
pub span: Span,
@ -267,7 +275,7 @@ pub(crate) struct ModuleInBlock {
}
#[derive(Subdiagnostic)]
#[help(expand_help)]
#[help("maybe `use` the module `{$name}` instead of redeclaring it")]
pub(crate) struct ModuleInBlockName {
#[primary_span]
pub span: Span,
@ -275,9 +283,11 @@ pub(crate) struct ModuleInBlockName {
}
#[derive(Diagnostic)]
#[diag(expand_module_file_not_found, code = E0583)]
#[help]
#[note]
#[diag("file not found for module `{$name}`", code = E0583)]
#[help("to create the module `{$name}`, create file \"{$default_path}\" or \"{$secondary_path}\"")]
#[note(
"if there is a `mod {$name}` elsewhere in the crate already, import it with `use crate::...` instead"
)]
pub(crate) struct ModuleFileNotFound {
#[primary_span]
pub span: Span,
@ -287,8 +297,8 @@ pub(crate) struct ModuleFileNotFound {
}
#[derive(Diagnostic)]
#[diag(expand_module_multiple_candidates, code = E0761)]
#[help]
#[diag("file for module `{$name}` found at both \"{$default_path}\" and \"{$secondary_path}\"", code = E0761)]
#[help("delete or rename one of them to remove the ambiguity")]
pub(crate) struct ModuleMultipleCandidates {
#[primary_span]
pub span: Span,
@ -298,14 +308,14 @@ pub(crate) struct ModuleMultipleCandidates {
}
#[derive(Diagnostic)]
#[diag(expand_trace_macro)]
#[diag("trace_macro")]
pub(crate) struct TraceMacro {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_proc_macro_panicked)]
#[diag("proc macro panicked")]
pub(crate) struct ProcMacroPanicked {
#[primary_span]
pub span: Span,
@ -314,13 +324,13 @@ pub(crate) struct ProcMacroPanicked {
}
#[derive(Subdiagnostic)]
#[help(expand_help)]
#[help("message: {$message}")]
pub(crate) struct ProcMacroPanickedHelp {
pub message: String,
}
#[derive(Diagnostic)]
#[diag(expand_proc_macro_derive_panicked)]
#[diag("proc-macro derive panicked")]
pub(crate) struct ProcMacroDerivePanicked {
#[primary_span]
pub span: Span,
@ -329,13 +339,13 @@ pub(crate) struct ProcMacroDerivePanicked {
}
#[derive(Subdiagnostic)]
#[help(expand_help)]
#[help("message: {$message}")]
pub(crate) struct ProcMacroDerivePanickedHelp {
pub message: String,
}
#[derive(Diagnostic)]
#[diag(expand_custom_attribute_panicked)]
#[diag("custom attribute panicked")]
pub(crate) struct CustomAttributePanicked {
#[primary_span]
pub span: Span,
@ -344,46 +354,46 @@ pub(crate) struct CustomAttributePanicked {
}
#[derive(Subdiagnostic)]
#[help(expand_help)]
#[help("message: {$message}")]
pub(crate) struct CustomAttributePanickedHelp {
pub message: String,
}
#[derive(Diagnostic)]
#[diag(expand_proc_macro_derive_tokens)]
#[diag("proc-macro derive produced unparsable tokens")]
pub(crate) struct ProcMacroDeriveTokens {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_duplicate_matcher_binding)]
#[diag("duplicate matcher binding")]
pub(crate) struct DuplicateMatcherBinding {
#[primary_span]
#[label]
#[label("duplicate binding")]
pub span: Span,
#[label(expand_label2)]
#[label("previous binding")]
pub prev: Span,
}
#[derive(LintDiagnostic)]
#[diag(expand_duplicate_matcher_binding)]
#[diag("duplicate matcher binding")]
pub(crate) struct DuplicateMatcherBindingLint {
#[label]
#[label("duplicate binding")]
pub span: Span,
#[label(expand_label2)]
#[label("previous binding")]
pub prev: Span,
}
#[derive(Diagnostic)]
#[diag(expand_missing_fragment_specifier)]
#[note]
#[help(expand_valid)]
#[diag("missing fragment specifier")]
#[note("fragment specifiers must be provided")]
#[help("{$valid}")]
pub(crate) struct MissingFragmentSpecifier {
#[primary_span]
pub span: Span,
#[suggestion(
expand_suggestion_add_fragspec,
"try adding a specifier here",
style = "verbose",
code = ":spec",
applicability = "maybe-incorrect"
@ -393,8 +403,8 @@ pub(crate) struct MissingFragmentSpecifier {
}
#[derive(Diagnostic)]
#[diag(expand_invalid_fragment_specifier)]
#[help]
#[diag("invalid fragment specifier `{$fragment}`")]
#[help("{$help}")]
pub(crate) struct InvalidFragmentSpecifier {
#[primary_span]
pub span: Span,
@ -403,7 +413,7 @@ pub(crate) struct InvalidFragmentSpecifier {
}
#[derive(Diagnostic)]
#[diag(expand_expected_paren_or_brace)]
#[diag("expected `(` or `{\"{\"}`, found `{$token}`")]
pub(crate) struct ExpectedParenOrBrace<'a> {
#[primary_span]
pub span: Span,
@ -411,7 +421,7 @@ pub(crate) struct ExpectedParenOrBrace<'a> {
}
#[derive(Diagnostic)]
#[diag(expand_empty_delegation_mac)]
#[diag("empty {$kind} delegation is not supported")]
pub(crate) struct EmptyDelegationMac {
#[primary_span]
pub span: Span,
@ -419,28 +429,28 @@ pub(crate) struct EmptyDelegationMac {
}
#[derive(Diagnostic)]
#[diag(expand_glob_delegation_outside_impls)]
#[diag("glob delegation is only supported in impls")]
pub(crate) struct GlobDelegationOutsideImpls {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_crate_name_in_cfg_attr)]
#[diag("`crate_name` within an `#![cfg_attr]` attribute is forbidden")]
pub(crate) struct CrateNameInCfgAttr {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_crate_type_in_cfg_attr)]
#[diag("`crate_type` within an `#![cfg_attr]` attribute is forbidden")]
pub(crate) struct CrateTypeInCfgAttr {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_glob_delegation_traitless_qpath)]
#[diag("qualified path without a trait in glob delegation")]
pub(crate) struct GlobDelegationTraitlessQpath {
#[primary_span]
pub span: Span,
@ -449,8 +459,10 @@ pub(crate) struct GlobDelegationTraitlessQpath {
// This used to be the `proc_macro_back_compat` lint (#83125). It was later
// turned into a hard error.
#[derive(Diagnostic)]
#[diag(expand_proc_macro_back_compat)]
#[note]
#[diag("using an old version of `{$crate_name}`")]
#[note(
"older versions of the `{$crate_name}` crate no longer compile; please update to `{$crate_name}` v{$fixed_version}, or switch to one of the `{$crate_name}` alternatives"
)]
pub(crate) struct ProcMacroBackCompat {
pub crate_name: String,
pub fixed_version: String,
@ -461,20 +473,35 @@ mod metavar_exprs {
use super::*;
#[derive(Diagnostic, Default)]
#[diag(expand_mve_extra_tokens)]
#[diag("unexpected trailing tokens")]
pub(crate) struct MveExtraTokens {
#[primary_span]
#[suggestion(code = "", applicability = "machine-applicable")]
#[suggestion(
"try removing {$extra_count ->
[one] this token
*[other] these tokens
}",
code = "",
applicability = "machine-applicable"
)]
pub span: Span,
#[label]
#[label("for this metavariable expression")]
pub ident_span: Span,
pub extra_count: usize,
// The rest is only used for specific diagnostics and can be default if neither
// `note` is `Some`.
#[note(expand_exact)]
#[note(
"the `{$name}` metavariable expression takes {$min_or_exact_args ->
[zero] no arguments
[one] a single argument
*[other] {$min_or_exact_args} arguments
}"
)]
pub exact_args_note: Option<()>,
#[note(expand_range)]
#[note(
"the `{$name}` metavariable expression takes between {$min_or_exact_args} and {$max_args} arguments"
)]
pub range_args_note: Option<()>,
pub min_or_exact_args: usize,
pub max_args: usize,
@ -482,30 +509,34 @@ mod metavar_exprs {
}
#[derive(Diagnostic)]
#[note]
#[diag(expand_mve_missing_paren)]
#[note("metavariable expressions use function-like parentheses syntax")]
#[diag("expected `(`")]
pub(crate) struct MveMissingParen {
#[primary_span]
#[label]
#[label("for this this metavariable expression")]
pub ident_span: Span,
#[label(expand_unexpected)]
#[label("unexpected token")]
pub unexpected_span: Option<Span>,
#[suggestion(code = "( /* ... */ )", applicability = "has-placeholders")]
#[suggestion(
"try adding parentheses",
code = "( /* ... */ )",
applicability = "has-placeholders"
)]
pub insert_span: Option<Span>,
}
#[derive(Diagnostic)]
#[note]
#[diag(expand_mve_unrecognized_expr)]
#[note("valid metavariable expressions are {$valid_expr_list}")]
#[diag("unrecognized metavariable expression")]
pub(crate) struct MveUnrecognizedExpr {
#[primary_span]
#[label]
#[label("not a valid metavariable expression")]
pub span: Span,
pub valid_expr_list: &'static str,
}
#[derive(Diagnostic)]
#[diag(expand_mve_unrecognized_var)]
#[diag("variable `{$key}` is not recognized in meta-variable expression")]
pub(crate) struct MveUnrecognizedVar {
#[primary_span]
pub span: Span,
@ -514,7 +545,7 @@ mod metavar_exprs {
}
#[derive(Diagnostic)]
#[diag(expand_macro_args_bad_delim)]
#[diag("`{$rule_kw}` rule argument matchers require parentheses")]
pub(crate) struct MacroArgsBadDelim {
#[primary_span]
pub span: Span,
@ -524,7 +555,10 @@ pub(crate) struct MacroArgsBadDelim {
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(expand_macro_args_bad_delim_sugg, applicability = "machine-applicable")]
#[multipart_suggestion(
"the delimiters should be `(` and `)`",
applicability = "machine-applicable"
)]
pub(crate) struct MacroArgsBadDelimSugg {
#[suggestion_part(code = "(")]
pub open: Span,
@ -533,37 +567,54 @@ pub(crate) struct MacroArgsBadDelimSugg {
}
#[derive(LintDiagnostic)]
#[diag(expand_macro_call_unused_doc_comment)]
#[help]
#[diag("unused doc comment")]
#[help(
"to document an item produced by a macro, the macro must produce the documentation as part of its expansion"
)]
pub(crate) struct MacroCallUnusedDocComment {
#[label]
#[label("rustdoc does not generate documentation for macro invocations")]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[diag(expand_or_patterns_back_compat)]
#[diag(
"the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro"
)]
pub(crate) struct OrPatternsBackCompat {
#[suggestion(code = "{suggestion}", applicability = "machine-applicable")]
#[suggestion(
"use pat_param to preserve semantics",
code = "{suggestion}",
applicability = "machine-applicable"
)]
pub span: Span,
pub suggestion: String,
}
#[derive(LintDiagnostic)]
#[diag(expand_trailing_semi_macro)]
#[diag("trailing semicolon in macro used in expression position")]
pub(crate) struct TrailingMacro {
#[note(expand_note1)]
#[note(expand_note2)]
#[note("macro invocations at the end of a block are treated as expressions")]
#[note(
"to ignore the value produced by the macro, add a semicolon after the invocation of `{$name}`"
)]
pub is_trailing: bool,
pub name: Ident,
}
#[derive(LintDiagnostic)]
#[diag(expand_unused_builtin_attribute)]
#[diag("unused attribute `{$attr_name}`")]
pub(crate) struct UnusedBuiltinAttribute {
#[note]
#[note(
"the built-in attribute `{$attr_name}` will be ignored, since it's applied to the macro invocation `{$macro_name}`"
)]
pub invoc_span: Span,
pub attr_name: Symbol,
pub macro_name: String,
#[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")]
#[suggestion(
"remove the attribute",
code = "",
applicability = "machine-applicable",
style = "tool-only"
)]
pub attr_span: Span,
}

View file

@ -19,7 +19,7 @@ use rustc_attr_parsing::{
};
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::PResult;
use rustc_errors::{PResult, inline_fluent};
use rustc_feature::Features;
use rustc_hir::Target;
use rustc_hir::def::MacroKinds;
@ -42,7 +42,6 @@ use crate::errors::{
RecursionLimitReached, RemoveExprNotSupported, RemoveNodeNotSupported, UnsupportedKeyValue,
WrongFragmentKind,
};
use crate::fluent_generated;
use crate::mbe::diagnostics::annotate_err_with_kind;
use crate::module::{
DirOwnership, ParsedExternalMod, mod_dir_path, mod_file_path_from_attr, parse_external_mod,
@ -1052,7 +1051,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
self.sess,
sym::proc_macro_hygiene,
item.span,
fluent_generated::expand_file_modules_in_proc_macro_input_are_unstable,
inline_fluent!("file modules in proc macro input are unstable"),
)
.emit();
}

View file

@ -26,5 +26,3 @@ pub mod proc_macro;
pub fn provide(providers: &mut rustc_middle::query::Providers) {
providers.derive_macro_expansion = proc_macro::provide_derive_macro_expansion;
}
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -302,12 +302,16 @@ pub(crate) fn annotate_err_with_kind(err: &mut Diag<'_>, kind: AstFragmentKind,
#[derive(Subdiagnostic)]
enum ExplainDocComment {
#[label(expand_explain_doc_comment_inner)]
#[label(
"inner doc comments expand to `#![doc = \"...\"]`, which is what this macro attempted to match"
)]
Inner {
#[primary_span]
span: Span,
},
#[label(expand_explain_doc_comment_outer)]
#[label(
"outer doc comments expand to `#[doc = \"...\"]`, which is what this macro attempted to match"
)]
Outer {
#[primary_span]
span: Span,

View file

@ -716,6 +716,23 @@ pub enum BorrowckGraphvizFormatKind {
TwoPhase,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub struct RustcCleanAttribute {
pub span: Span,
pub cfg: Symbol,
pub except: Option<RustcCleanQueries>,
pub loaded_from_disk: Option<RustcCleanQueries>,
}
/// Represents the `except=` or `loaded_from_disk=` argument of `#[rustc_clean]`
#[derive(Clone, Debug, PartialEq, Eq)]
#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub struct RustcCleanQueries {
pub entries: ThinVec<Symbol>,
pub span: Span,
}
/// Represents parsed *built-in* inert attributes.
///
/// ## Overview
@ -992,6 +1009,9 @@ pub enum AttributeKind {
/// Represents [`#[recursion_limit]`](https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute)
RecursionLimit { attr_span: Span, limit_span: Span, limit: Limit },
/// Represents `#[reexport_test_harness_main]`
ReexportTestHarnessMain(Symbol),
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
@ -1022,6 +1042,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_builtin_macro]`.
RustcBuiltinMacro { builtin_name: Option<Symbol>, helper_attrs: ThinVec<Symbol>, span: Span },
/// Represents `#[rustc_clean]`
RustcClean(ThinVec<RustcCleanAttribute>),
/// Represents `#[rustc_coherence_is_core]`
RustcCoherenceIsCore(Span),
@ -1077,6 +1100,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_hidden_type_of_opaques]`
RustcHiddenTypeOfOpaques,
/// Represents `#[rustc_if_this_changed]`
RustcIfThisChanged(Span, Option<Symbol>),
/// Represents `#[rustc_layout]`
RustcLayout(ThinVec<RustcLayoutType>),
@ -1178,6 +1204,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_std_internal_symbol]`.
RustcStdInternalSymbol(Span),
/// Represents `#[rustc_then_this_would_need]`
RustcThenThisWouldNeed(Span, ThinVec<Ident>),
/// Represents `#[rustc_unsafe_specialization_marker]`.
RustcUnsafeSpecializationMarker(Span),

View file

@ -87,6 +87,7 @@ impl AttributeKind {
ProcMacroDerive { .. } => No,
ProfilerRuntime => No,
RecursionLimit { .. } => No,
ReexportTestHarnessMain(..) => No,
Repr { .. } => No,
RustcAllocator => No,
RustcAllocatorZeroed => No,
@ -96,6 +97,7 @@ impl AttributeKind {
RustcAsPtr(..) => Yes,
RustcBodyStability { .. } => No,
RustcBuiltinMacro { .. } => Yes,
RustcClean { .. } => No,
RustcCoherenceIsCore(..) => No,
RustcCoinductive(..) => No,
RustcConfusables { .. } => Yes,
@ -112,6 +114,7 @@ impl AttributeKind {
RustcDynIncompatibleTrait(..) => No,
RustcHasIncoherentInherentImpls => Yes,
RustcHiddenTypeOfOpaques => No,
RustcIfThisChanged(..) => No,
RustcLayout(..) => No,
RustcLayoutScalarValidRangeEnd(..) => Yes,
RustcLayoutScalarValidRangeStart(..) => Yes,
@ -144,6 +147,7 @@ impl AttributeKind {
RustcSkipDuringMethodDispatch { .. } => No,
RustcSpecializationTrait(..) => No,
RustcStdInternalSymbol(..) => No,
RustcThenThisWouldNeed(..) => No,
RustcUnsafeSpecializationMarker(..) => No,
RustcVariance => No,
RustcVarianceOfOpaques => No,

View file

@ -6,7 +6,7 @@ use rustc_abi::Align;
use rustc_ast::attr::data_structures::CfgEntry;
use rustc_ast::attr::version::RustcVersion;
use rustc_ast::token::{CommentKind, DocFragmentKind};
use rustc_ast::{AttrStyle, IntTy, UintTy};
use rustc_ast::{AttrId, AttrStyle, IntTy, UintTy};
use rustc_ast_pretty::pp::Printer;
use rustc_data_structures::fx::FxIndexMap;
use rustc_span::def_id::DefId;
@ -179,7 +179,7 @@ macro_rules! print_tup {
}
print_tup!(A B C D E F G H);
print_skip!(Span, (), ErrorGuaranteed);
print_skip!(Span, (), ErrorGuaranteed, AttrId);
print_disp!(u8, u16, u128, usize, bool, NonZero<u32>, Limit);
print_debug!(
Symbol,

View file

@ -1,6 +1,7 @@
// ignore-tidy-filelength
use std::borrow::Cow;
use std::fmt;
use std::ops::Not;
use rustc_abi::ExternAbi;
use rustc_ast::attr::AttributeExt;
@ -1012,10 +1013,14 @@ impl<'hir> Generics<'hir> {
span_for_parentheses.map_or_else(
|| {
// We include bounds that come from a `#[derive(_)]` but point at the user's code,
// as we use this method to get a span appropriate for suggestions.
// We include bounds that come from a `#[derive(_)]` but point at the user's
// code, as we use this method to get a span appropriate for suggestions.
let bs = bound.span();
bs.can_be_used_for_suggestions().then(|| (bs.shrink_to_hi(), None))
// We use `from_expansion` instead of `can_be_used_for_suggestions` because
// the trait bound from imperfect derives do point at the type parameter,
// but expanded to a where clause, so we want to ignore those. This is only
// true for derive intrinsics.
bs.from_expansion().not().then(|| (bs.shrink_to_hi(), None))
},
|span| Some((span.shrink_to_hi(), Some(span.shrink_to_lo()))),
)

View file

@ -142,6 +142,7 @@ hir_analysis_copy_impl_on_non_adt =
hir_analysis_copy_impl_on_type_with_dtor =
the trait `Copy` cannot be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
.note = destructor declared here
hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type, not `{$self_ty}`
.label = can't implement cross-crate trait with a default impl for non-struct/enum type

View file

@ -122,9 +122,10 @@ fn visit_implementation_of_copy(checker: &Checker<'_>) -> Result<(), ErrorGuaran
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::CopyImplOnNonAdt { span }))
}
Err(CopyImplementationError::HasDestructor) => {
Err(CopyImplementationError::HasDestructor(did)) => {
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;
Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span }))
let impl_ = tcx.def_span(did);
Err(tcx.dcx().emit_err(errors::CopyImplOnTypeWithDtor { span, impl_ }))
}
Err(CopyImplementationError::HasUnsafeFields) => {
let span = tcx.hir_expect_item(impl_did).expect_impl().self_ty.span;

View file

@ -278,6 +278,8 @@ pub(crate) struct CopyImplOnTypeWithDtor {
#[primary_span]
#[label]
pub span: Span,
#[note]
pub impl_: Span,
}
#[derive(Diagnostic)]

View file

@ -592,7 +592,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if span.can_be_used_for_suggestions()
&& poly_trait_ref.trait_ref.trait_def_id().is_some()
&& !self.maybe_suggest_impl_trait(span, hir_id, hir_bounds, &mut diag)
&& !self.maybe_suggest_dyn_trait(hir_id, sugg, &mut diag)
&& !self.maybe_suggest_dyn_trait(hir_id, span, sugg, &mut diag)
{
self.maybe_suggest_add_generic_impl_trait(span, hir_id, &mut diag);
}
@ -750,10 +750,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
fn maybe_suggest_dyn_trait(
&self,
hir_id: hir::HirId,
span: Span,
sugg: Vec<(Span, String)>,
diag: &mut Diag<'_>,
) -> bool {
let tcx = self.tcx();
if span.in_derive_expansion() {
return false;
}
// Look at the direct HIR parent, since we care about the relationship between
// the type and the thing that directly encloses it.

View file

@ -10,7 +10,6 @@ rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_analysis = { path = "../rustc_hir_analysis" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }

View file

@ -1,315 +0,0 @@
hir_typeck_abi_cannot_be_called =
functions with the {$abi} ABI cannot be called
.note = an `extern {$abi}` function can only be called using inline assembly
hir_typeck_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function
hir_typeck_add_return_type_add = try adding a return type
hir_typeck_add_return_type_missing_here = a return type might be missing here
hir_typeck_address_of_temporary_taken = cannot take address of a temporary
.label = temporary value
hir_typeck_arg_mismatch_indeterminate = argument type mismatch was detected, but rustc had trouble determining where
.note = we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new
hir_typeck_as_deref_suggestion = consider using `as_deref` here
hir_typeck_base_expression_double_dot = base expression required after `..`
hir_typeck_base_expression_double_dot_add_expr = add a base expression here
hir_typeck_base_expression_double_dot_enable_default_field_values =
add `#![feature(default_field_values)]` to the crate attributes to enable default values on `struct` fields
hir_typeck_base_expression_double_dot_remove = remove the `..` as all the fields are already present
hir_typeck_break_inside_closure =
`{$name}` inside of a closure
.label = cannot `{$name}` inside of a closure
.closure_label = enclosing closure
hir_typeck_break_inside_coroutine =
`{$name}` inside `{$kind}` {$source}
.label = cannot `{$name}` inside `{$kind}` {$source}
.coroutine_label = enclosing `{$kind}` {$source}
hir_typeck_break_non_loop =
`break` with value from a `{$kind}` loop
.label = can only break with a value inside `loop` or breakable block
.label2 = you can't `break` with a value in a `{$kind}` 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
hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`{$action_or_ty ->
[NONE] {""}
[implement] , perhaps you need to implement it
*[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it
}
hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool`
.suggestion = compare with zero instead
.help = compare with zero instead
.label = unsupported cast
hir_typeck_cant_dereference = type `{$ty}` cannot be dereferenced
hir_typeck_cant_dereference_label = can't be dereferenced
hir_typeck_cast_enum_drop = cannot cast enum `{$expr_ty}` into integer `{$cast_ty}` because it implements `Drop`
hir_typeck_cast_thin_pointer_to_wide_pointer = cannot cast thin pointer `{$expr_ty}` to wide pointer `{$cast_ty}`
.teach_help = Thin pointers are "simple" pointers: they are purely a reference to a
memory address.
Wide pointers are pointers referencing "Dynamically Sized Types" (also
called DST). DST don't have a statically known size, therefore they can
only exist behind some kind of pointers that contain additional
information. Slices and trait objects are DSTs. In the case of slices,
the additional information the wide pointer holds is their size.
To fix this error, don't try to cast directly between thin and wide
pointers.
For more information about casts, take a look at The Book:
https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions",
hir_typeck_cast_unknown_pointer = cannot cast {$to ->
[true] to
*[false] from
} a pointer of an unknown kind
.label_to = needs more type information
.note = the type information given here is insufficient to check whether the pointer cast is valid
.label_from = the type information given here is insufficient to check whether the pointer cast is valid
hir_typeck_const_continue_bad_label =
`#[const_continue]` must break to a labeled block that participates in a `#[loop_match]`
hir_typeck_continue_labeled_block =
`continue` pointing to a labeled block
.label = labeled blocks cannot be `continue`'d
.block_label = labeled block the `continue` points to
hir_typeck_convert_to_str = try converting the passed type into a `&str`
hir_typeck_convert_using_method = try using `{$sugg}` to convert `{$found}` to `{$expected}`
hir_typeck_ctor_is_private = tuple struct constructor `{$def}` is private
hir_typeck_dependency_on_unit_never_type_fallback = this function depends on never type fallback being `()`
.note = in edition 2024, the requirement `{$obligation}` will fail
.help = specify the types explicitly
hir_typeck_deref_is_empty = this expression `Deref`s to `{$deref_ty}` which implements `is_empty`
hir_typeck_expected_array_or_slice = expected an array or slice, found `{$ty}`
hir_typeck_expected_array_or_slice_label = pattern cannot match with input type `{$ty}`
hir_typeck_expected_default_return_type = expected `()` because of default return type
hir_typeck_expected_return_type = expected `{$expected}` because of return type
hir_typeck_explicit_destructor = explicit use of destructor method
.label = explicit destructor calls not allowed
.suggestion = consider using `drop` function
hir_typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
.previous_use_label = first use of `{$ident}`
hir_typeck_fn_item_to_variadic_function = can't pass a function item to a variadic function
.suggestion = use a function pointer instead
.help = a function item is zero-sized and needs to be cast into a function pointer to be used in FFI
.note = for more information on function items, visit https://doc.rust-lang.org/reference/types/function-item.html
hir_typeck_fru_expr = this expression does not end in a comma...
hir_typeck_fru_expr2 = ... so this is interpreted as a `..` range expression, instead of functional record update syntax
hir_typeck_fru_note = this expression may have been misinterpreted as a `..` range expression
hir_typeck_fru_suggestion =
to set the remaining fields{$expr ->
[NONE]{""}
*[other] {" "}from `{$expr}`
}, separate the last named field with a comma
hir_typeck_functional_record_update_on_non_struct =
functional record update syntax requires a struct
hir_typeck_gpu_kernel_abi_cannot_be_called =
functions with the "gpu-kernel" ABI cannot be called
.note = an `extern "gpu-kernel"` function must be launched on the GPU by the runtime
hir_typeck_help_set_edition_cargo = set `edition = "{$edition}"` in `Cargo.toml`
hir_typeck_help_set_edition_standalone = pass `--edition {$edition}` to `rustc`
hir_typeck_int_to_fat = cannot cast `{$expr_ty}` to a pointer that {$known_wide ->
[true] is
*[false] may be
} wide
hir_typeck_int_to_fat_label = creating a `{$cast_ty}` requires both an address and {$metadata}
hir_typeck_int_to_fat_label_nightly = consider casting this expression to `*const ()`, then using `core::ptr::from_raw_parts`
hir_typeck_invalid_callee = expected function, found {$found}
hir_typeck_invalid_defined = `{$path}` defined here
hir_typeck_invalid_defined_kind = {$kind} `{$path}` defined here
hir_typeck_invalid_fn_defined = `{$func}` defined here returns `{$ty}`
hir_typeck_invalid_local = `{$local_name}` has type `{$ty}`
hir_typeck_lossy_provenance_int2ptr =
strict provenance disallows casting integer `{$expr_ty}` to pointer `{$cast_ty}`
.suggestion = use `.with_addr()` to adjust a valid pointer in the same allocation, to this address
.help = if you can't comply with strict provenance and don't have a pointer with the correct provenance you can use `std::ptr::with_exposed_provenance()` instead
hir_typeck_lossy_provenance_ptr2int =
under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`
.suggestion = use `.addr()` to obtain the address of a pointer
.help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
hir_typeck_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty}`
hir_typeck_naked_asm_outside_naked_fn =
the `naked_asm!` macro can only be used in functions marked with `#[unsafe(naked)]`
hir_typeck_naked_functions_asm_block =
naked functions must contain a single `naked_asm!` invocation
.label_multiple_asm = multiple `naked_asm!` invocations are not allowed in naked functions
.label_non_asm = not allowed in naked functions
hir_typeck_naked_functions_must_naked_asm =
the `asm!` macro is not allowed in naked functions
.label = consider using the `naked_asm!` macro instead
hir_typeck_never_type_fallback_flowing_into_unsafe_call = never type fallback affects this call to an `unsafe` function
.help = specify the type explicitly
hir_typeck_never_type_fallback_flowing_into_unsafe_deref = never type fallback affects this raw pointer dereference
.help = specify the type explicitly
hir_typeck_never_type_fallback_flowing_into_unsafe_method = never type fallback affects this call to an `unsafe` method
.help = specify the type explicitly
hir_typeck_never_type_fallback_flowing_into_unsafe_path = never type fallback affects this `unsafe` function
.help = specify the type explicitly
hir_typeck_never_type_fallback_flowing_into_unsafe_union_field = never type fallback affects this union access
.help = specify the type explicitly
hir_typeck_no_associated_item = no {$item_kind} named `{$item_ident}` found for {$ty_prefix} `{$ty}`{$trait_missing_method ->
[true] {""}
*[other] {" "}in the current scope
}
hir_typeck_no_field_on_type = no field `{$field}` on type `{$ty}`
hir_typeck_no_field_on_variant = no field named `{$field}` on enum variant `{$container}::{$ident}`
hir_typeck_no_field_on_variant_enum = this enum variant...
hir_typeck_no_field_on_variant_field = ...does not have this field
hir_typeck_no_patterns =
patterns not allowed in naked function parameters
hir_typeck_note_caller_chooses_ty_for_ty_param = the caller chooses a type for `{$ty_param_name}` which can be different from `{$found_ty}`
hir_typeck_note_edition_guide = for more on editions, read https://doc.rust-lang.org/edition-guide
hir_typeck_option_result_asref = use `{$def_path}::as_ref` to convert `{$expected_ty}` to `{$expr_ty}`
hir_typeck_option_result_cloned = use `{$def_path}::cloned` to clone the value inside the `{$def_path}`
hir_typeck_option_result_copied = use `{$def_path}::copied` to copy the value inside the `{$def_path}`
hir_typeck_outside_loop =
`{$name}` outside of a loop{$is_break ->
[true] {" or labeled block"}
*[false] {""}
}
.label = cannot `{$name}` outside of a loop{$is_break ->
[true] {" or labeled block"}
*[false] {""}
}
hir_typeck_outside_loop_suggestion = consider labeling this block to be able to break within it
hir_typeck_params_not_allowed =
referencing function parameters is not allowed in naked functions
.help = follow the calling convention in asm block to use parameters
hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
.suggestion = cast the value to `{$cast_ty}`
.teach_help = certain types, like `{$ty}`, must be cast before passing them to a variadic function to match the implicit cast that a C compiler would perform as part of C's numeric promotion rules
hir_typeck_project_on_non_pin_project_type = cannot project on type that is not `#[pin_v2]`
.note = type defined here
.suggestion = add `#[pin_v2]` here
hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len ->
[1] auto trait {$traits}
*[other] auto traits {$traits}
} to dyn bound via pointer cast
.note = this could allow UB elsewhere
.help = use `transmute` if you're sure this is sound
.label = unsupported cast
hir_typeck_register_type_unstable =
type `{$ty}` cannot be used with this register class in stable
hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression
hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression
hir_typeck_remove_semi_for_coerce_ret = the `match` arms can conform to this return type
hir_typeck_remove_semi_for_coerce_semi = the `match` is a statement because of this semicolon, consider removing it
hir_typeck_remove_semi_for_coerce_suggestion = remove this semicolon
hir_typeck_replace_comma_with_semicolon = replace the comma with a semicolon to create {$descr}
hir_typeck_return_stmt_outside_of_fn_body =
{$statement_kind} statement outside of function body
.encl_body_label = the {$statement_kind} is part of this body...
.encl_fn_label = ...not the enclosing function body
hir_typeck_rpit_box_return_expr = if you change the return type to expect trait objects, box the returned expressions
hir_typeck_rpit_change_return_type = you could change the return type to be a boxed trait object
hir_typeck_rustcall_incorrect_args =
functions with the "rust-call" ABI must take a single non-self tuple argument
hir_typeck_self_ctor_from_outer_item = can't reference `Self` constructor from outer item
.label = the inner item doesn't inherit generics from this impl, so `Self` is invalid to reference
.suggestion = replace `Self` with the actual type
hir_typeck_self_ctor_from_outer_item_inner_item = `Self` used in this inner item
hir_typeck_slicing_suggestion = consider slicing here
hir_typeck_struct_expr_non_exhaustive =
cannot create non-exhaustive {$what} using struct expression
hir_typeck_suggest_boxing_note = for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
hir_typeck_suggest_boxing_when_appropriate = store this in the heap by calling `Box::new`
hir_typeck_suggest_ptr_null_mut = consider using `core::ptr::null_mut` instead
hir_typeck_supertrait_item_multiple_shadowee = items from several supertraits are shadowed: {$traits}
hir_typeck_supertrait_item_shadowee = item from `{$supertrait}` is shadowed by a subtrait item
hir_typeck_supertrait_item_shadower = item from `{$subtrait}` shadows a supertrait item
hir_typeck_supertrait_item_shadowing = trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait
hir_typeck_trivial_cast = trivial {$numeric ->
[true] numeric cast
*[false] cast
}: `{$expr_ty}` as `{$cast_ty}`
.help = cast can be replaced by coercion; this might require a temporary variable
hir_typeck_union_pat_dotdot = `..` cannot be used in union patterns
hir_typeck_union_pat_multiple_fields = union patterns should have exactly one field
hir_typeck_unlabeled_cf_in_while_condition =
`break` or `continue` with no label in the condition of a `while` loop
.label = unlabeled `{$cf_type}` in the condition of a `while` loop
hir_typeck_unlabeled_in_labeled_block =
unlabeled `{$cf_type}` inside of a labeled block
.label = `{$cf_type}` statements that would diverge to or through a labeled block need to bear a label
hir_typeck_use_is_empty =
consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything
hir_typeck_yield_expr_outside_of_coroutine =
yield expression outside of coroutine literal

View file

@ -2,7 +2,7 @@ use std::iter;
use rustc_abi::{CanonAbi, ExternAbi};
use rustc_ast::util::parser::ExprPrecedence;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey};
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, StashKey, inline_fluent};
use rustc_hir::def::{self, CtorKind, Namespace, Res};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, HirId, LangItem};
@ -25,8 +25,8 @@ use tracing::{debug, instrument};
use super::method::MethodCallee;
use super::method::probe::ProbeScope;
use super::{Expectation, FnCtxt, TupleArgumentsFlag};
use crate::errors;
use crate::method::TreatNotYetDefinedOpaques;
use crate::{errors, fluent_generated};
/// Checks that it is legal to call methods of the trait corresponding
/// to `trait_id` (this only cares about the trait, not the specific
@ -832,12 +832,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(Some((_, kind, path)), _) => {
err.arg("kind", kind);
err.arg("path", path);
Some(fluent_generated::hir_typeck_invalid_defined_kind)
Some(inline_fluent!("{$kind} `{$path}` defined here"))
}
(_, Some(hir::QPath::Resolved(_, path))) => {
self.tcx.sess.source_map().span_to_snippet(path.span).ok().map(|p| {
err.arg("func", p);
fluent_generated::hir_typeck_invalid_fn_defined
inline_fluent!("`{$func}` defined here returns `{$ty}`")
})
}
_ => {
@ -846,15 +846,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// type definitions themselves, but rather variables *of* that type.
Res::Local(hir_id) => {
err.arg("local_name", self.tcx.hir_name(hir_id));
Some(fluent_generated::hir_typeck_invalid_local)
Some(inline_fluent!("`{$local_name}` has type `{$ty}`"))
}
Res::Def(kind, def_id) if kind.ns() == Some(Namespace::ValueNS) => {
err.arg("path", self.tcx.def_path_str(def_id));
Some(fluent_generated::hir_typeck_invalid_defined)
Some(inline_fluent!("`{$path}` defined here"))
}
_ => {
err.arg("path", callee_ty);
Some(fluent_generated::hir_typeck_invalid_defined)
Some(inline_fluent!("`{$path}` defined here"))
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -5,7 +5,7 @@ use core::iter;
use hir::def_id::LocalDefId;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_data_structures::packed::Pu128;
use rustc_errors::{Applicability, Diag, MultiSpan, listify};
use rustc_errors::{Applicability, Diag, MultiSpan, inline_fluent, listify};
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{
@ -33,10 +33,10 @@ use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _
use tracing::{debug, instrument};
use super::FnCtxt;
use crate::errors;
use crate::fn_ctxt::rustc_span::BytePos;
use crate::method::probe;
use crate::method::probe::{IsSuggestion, Mode, ProbeScope};
use crate::{errors, fluent_generated as fluent};
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn body_fn_sig(&self) -> Option<ty::FnSig<'tcx>> {
@ -482,7 +482,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let sugg = prefix_wrap(".map(|x| x.as_str())");
err.span_suggestion_verbose(
expr.span.shrink_to_hi(),
fluent::hir_typeck_convert_to_str,
inline_fluent!("try converting the passed type into a `&str`"),
sugg,
Applicability::MachineApplicable,
);
@ -1932,25 +1932,94 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
None,
);
} else {
let mut suggest_derive = true;
if let Some(errors) =
self.type_implements_trait_shallow(clone_trait_did, expected_ty, self.param_env)
{
let manually_impl = "consider manually implementing `Clone` to avoid the \
implicit type parameter bounds";
match &errors[..] {
[] => {}
[error] => {
diag.help(format!(
"`Clone` is not implemented because the trait bound `{}` is \
not satisfied",
error.obligation.predicate,
));
let msg = "`Clone` is not implemented because a trait bound is not \
satisfied";
if let traits::ObligationCauseCode::ImplDerived(data) =
error.obligation.cause.code()
{
let mut span: MultiSpan = data.span.into();
if self.tcx.is_automatically_derived(data.impl_or_alias_def_id) {
span.push_span_label(
data.span,
format!(
"derive introduces an implicit `{}` bound",
error.obligation.predicate
),
);
}
diag.span_help(span, msg);
if self.tcx.is_automatically_derived(data.impl_or_alias_def_id)
&& data.impl_or_alias_def_id.is_local()
{
diag.help(manually_impl);
suggest_derive = false;
}
} else {
diag.help(msg);
}
}
_ => {
diag.help(format!(
"`Clone` is not implemented because the following trait bounds \
could not be satisfied: {}",
listify(&errors, |e| format!("`{}`", e.obligation.predicate))
.unwrap(),
));
let unsatisfied_bounds: Vec<_> = errors
.iter()
.filter_map(|error| match error.obligation.cause.code() {
traits::ObligationCauseCode::ImplDerived(data) => {
let pre = if self
.tcx
.is_automatically_derived(data.impl_or_alias_def_id)
{
"derive introduces an implicit "
} else {
""
};
Some((
data.span,
format!(
"{pre}unsatisfied trait bound `{}`",
error.obligation.predicate
),
))
}
_ => None,
})
.collect();
let msg = "`Clone` is not implemented because the some trait bounds \
could not be satisfied";
if errors.len() == unsatisfied_bounds.len() {
let mut unsatisfied_bounds_spans: MultiSpan = unsatisfied_bounds
.iter()
.map(|(span, _)| *span)
.collect::<Vec<Span>>()
.into();
for (span, label) in unsatisfied_bounds {
unsatisfied_bounds_spans.push_span_label(span, label);
}
diag.span_help(unsatisfied_bounds_spans, msg);
if errors.iter().all(|error| match error.obligation.cause.code() {
traits::ObligationCauseCode::ImplDerived(data) => {
self.tcx.is_automatically_derived(data.impl_or_alias_def_id)
&& data.impl_or_alias_def_id.is_local()
}
_ => false,
}) {
diag.help(manually_impl);
suggest_derive = false;
}
} else {
diag.help(format!(
"{msg}: {}",
listify(&errors, |e| format!("`{}`", e.obligation.predicate))
.unwrap(),
));
}
}
}
for error in errors {
@ -1968,7 +2037,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
}
self.suggest_derive(diag, &vec![(trait_ref.upcast(self.tcx), None, None)]);
if suggest_derive {
self.suggest_derive(diag, &vec![(trait_ref.upcast(self.tcx), None, None)]);
}
}
}
}

View file

@ -67,8 +67,6 @@ use crate::expectation::Expectation;
use crate::fn_ctxt::LoweredTy;
use crate::gather_locals::GatherLocalsVisitor;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
#[macro_export]
macro_rules! type_error_struct {
($dcx:expr, $span:expr, $typ:expr, $code:expr, $($message:tt)*) => ({

View file

@ -1748,19 +1748,34 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Find all the requirements that come from a local `impl` block.
let mut skip_list: UnordSet<_> = Default::default();
let mut spanned_predicates = FxIndexMap::default();
let mut manually_impl = false;
for (p, parent_p, cause) in unsatisfied_predicates {
// Extract the predicate span and parent def id of the cause,
// if we have one.
let (item_def_id, cause_span) = match cause.as_ref().map(|cause| cause.code()) {
Some(ObligationCauseCode::ImplDerived(data)) => {
(data.impl_or_alias_def_id, data.span)
}
Some(
ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _)
| ObligationCauseCode::WhereClause(def_id, span),
) if !span.is_dummy() => (*def_id, *span),
_ => continue,
};
let (item_def_id, cause_span, cause_msg) =
match cause.as_ref().map(|cause| cause.code()) {
Some(ObligationCauseCode::ImplDerived(data)) => {
let msg = if let DefKind::Impl { of_trait: true } =
self.tcx.def_kind(data.impl_or_alias_def_id)
{
format!(
"type parameter would need to implement `{}`",
self.tcx
.item_name(self.tcx.impl_trait_id(data.impl_or_alias_def_id))
)
} else {
format!("unsatisfied bound `{p}` introduced here")
};
(data.impl_or_alias_def_id, data.span, msg)
}
Some(
ObligationCauseCode::WhereClauseInExpr(def_id, span, _, _)
| ObligationCauseCode::WhereClause(def_id, span),
) if !span.is_dummy() => {
(*def_id, *span, format!("unsatisfied bound `{p}` introduced here"))
}
_ => continue,
};
// Don't point out the span of `WellFormed` predicates.
if !matches!(
@ -1791,13 +1806,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let entry = entry.or_insert_with(|| {
(FxIndexSet::default(), FxIndexSet::default(), Vec::new())
});
entry.0.insert(span);
entry.0.insert(cause_span);
entry.1.insert((
span,
"unsatisfied trait bound introduced in this `derive` macro",
cause_span,
cause_msg,
));
entry.2.push(p);
skip_list.insert(p);
manually_impl = true;
}
// Unmet obligation coming from an `impl`.
@ -1842,7 +1858,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
entry.2.push(p);
if cause_span != *item_span {
entry.0.insert(cause_span);
entry.1.insert((cause_span, "unsatisfied trait bound introduced here"));
entry.1.insert((cause_span, "unsatisfied trait bound introduced here".to_string()));
} else {
if let Some(of_trait) = of_trait {
entry.0.insert(of_trait.trait_ref.path.span);
@ -1850,9 +1866,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
entry.0.insert(self_ty.span);
};
if let Some(of_trait) = of_trait {
entry.1.insert((of_trait.trait_ref.path.span, ""));
entry.1.insert((of_trait.trait_ref.path.span, String::new()));
}
entry.1.insert((self_ty.span, ""));
entry.1.insert((self_ty.span, String::new()));
}
Some(Node::Item(hir::Item {
kind: hir::ItemKind::Trait(_, rustc_ast::ast::IsAuto::Yes, ..),
@ -1881,8 +1897,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
(FxIndexSet::default(), FxIndexSet::default(), Vec::new())
});
entry.0.insert(cause_span);
entry.1.insert((ident.span, ""));
entry.1.insert((cause_span, "unsatisfied trait bound introduced here"));
entry.1.insert((ident.span, String::new()));
entry.1.insert((cause_span, "unsatisfied trait bound introduced here".to_string()));
entry.2.push(p);
}
_ => {
@ -2083,6 +2099,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
*suggested_derive = self.suggest_derive(err, unsatisfied_predicates);
*unsatisfied_bounds = true;
}
if manually_impl {
err.help("consider manually implementing the trait to avoid undesired bounds");
}
}
/// If an appropriate error source is not found, check method chain for possible candidates

View file

@ -6,7 +6,6 @@ edition = "2024"
[dependencies]
# tidy-alphabetical-start
rand = "0.9.0"
rustc_ast = { path = "../rustc_ast" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fs_util = { path = "../rustc_fs_util" }
@ -18,6 +17,5 @@ rustc_middle = { path = "../rustc_middle" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
thin-vec = "0.2.12"
tracing = "0.1"
# tidy-alphabetical-end

View file

@ -5,7 +5,7 @@
//! annotations. These annotations can be used to test whether paths
//! exist in the graph. These checks run after codegen, so they view the
//! the final state of the dependency graph. Note that there are
//! similar assertions found in `persist::dirty_clean` which check the
//! similar assertions found in `persist::clean` which check the
//! **initial** state of the dependency graph, just after it has been
//! loaded from disk.
//!
@ -39,14 +39,16 @@ use std::io::Write;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::graph::linked_graph::{Direction, INCOMING, NodeIndex, OUTGOING};
use rustc_hir::Attribute;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::{CRATE_DEF_ID, DefId, LocalDefId};
use rustc_hir::intravisit::{self, Visitor};
use rustc_middle::bug;
use rustc_middle::dep_graph::{
DepGraphQuery, DepKind, DepNode, DepNodeExt, DepNodeFilter, EdgeFilter, dep_kinds,
};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_middle::{bug, span_bug};
use rustc_span::{Span, Symbol, sym};
use tracing::debug;
use {rustc_graphviz as dot, rustc_hir as hir};
@ -105,29 +107,13 @@ struct IfThisChanged<'tcx> {
}
impl<'tcx> IfThisChanged<'tcx> {
fn argument(&self, attr: &hir::Attribute) -> Option<Symbol> {
let mut value = None;
for list_item in attr.meta_item_list().unwrap_or_default() {
match list_item.ident() {
Some(ident) if list_item.is_word() && value.is_none() => value = Some(ident.name),
_ =>
// FIXME better-encapsulate meta_item (don't directly access `node`)
{
span_bug!(list_item.span(), "unexpected meta-item {:?}", list_item)
}
}
}
value
}
fn process_attrs(&mut self, def_id: LocalDefId) {
let def_path_hash = self.tcx.def_path_hash(def_id.to_def_id());
let hir_id = self.tcx.local_def_id_to_hir_id(def_id);
let attrs = self.tcx.hir_attrs(hir_id);
for attr in attrs {
if attr.has_name(sym::rustc_if_this_changed) {
let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned {
if let Attribute::Parsed(AttributeKind::RustcIfThisChanged(span, dep_node)) = *attr {
let dep_node = match dep_node {
None => DepNode::from_def_path_hash(
self.tcx,
def_path_hash,
@ -136,36 +122,29 @@ impl<'tcx> IfThisChanged<'tcx> {
Some(n) => {
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
Ok(n) => n,
Err(()) => self.tcx.dcx().emit_fatal(errors::UnrecognizedDepNode {
span: attr.span(),
name: n,
}),
Err(()) => self
.tcx
.dcx()
.emit_fatal(errors::UnrecognizedDepNode { span, name: n }),
}
}
};
self.if_this_changed.push((attr.span(), def_id.to_def_id(), dep_node));
} else if attr.has_name(sym::rustc_then_this_would_need) {
let dep_node_interned = self.argument(attr);
let dep_node = match dep_node_interned {
Some(n) => {
match DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash) {
Ok(n) => n,
Err(()) => self.tcx.dcx().emit_fatal(errors::UnrecognizedDepNode {
span: attr.span(),
name: n,
}),
}
}
None => {
self.tcx.dcx().emit_fatal(errors::MissingDepNode { span: attr.span() });
}
};
self.then_this_would_need.push((
attr.span(),
dep_node_interned.unwrap(),
hir_id,
dep_node,
));
self.if_this_changed.push((span, def_id.to_def_id(), dep_node));
} else if let Attribute::Parsed(AttributeKind::RustcThenThisWouldNeed(
_,
ref dep_nodes,
)) = *attr
{
for &n in dep_nodes {
let Ok(dep_node) =
DepNode::from_label_string(self.tcx, n.as_str(), def_path_hash)
else {
self.tcx
.dcx()
.emit_fatal(errors::UnrecognizedDepNode { span: n.span, name: n.name });
};
self.then_this_would_need.push((n.span, n.name, hir_id, dep_node));
}
}
}
}

View file

@ -1,7 +1,7 @@
use std::path::{Path, PathBuf};
use rustc_macros::Diagnostic;
use rustc_span::{Ident, Span, Symbol};
use rustc_span::{Span, Symbol};
#[derive(Diagnostic)]
#[diag("unrecognized `DepNode` variant: {$name}")]
@ -11,13 +11,6 @@ pub(crate) struct UnrecognizedDepNode {
pub name: Symbol,
}
#[derive(Diagnostic)]
#[diag("missing `DepNode` variant")]
pub(crate) struct MissingDepNode {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag("no `#[rustc_if_this_changed]` annotation detected")]
pub(crate) struct MissingIfThisChanged {
@ -106,42 +99,12 @@ pub(crate) struct NotLoaded<'a> {
pub dep_node_str: &'a str,
}
#[derive(Diagnostic)]
#[diag("unknown `rustc_clean` argument")]
pub(crate) struct UnknownRustcCleanArgument {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag("no cfg attribute")]
pub(crate) struct NoCfg {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag("associated value expected for `{$ident}`")]
pub(crate) struct AssociatedValueExpectedFor {
#[primary_span]
pub span: Span,
pub ident: Ident,
}
#[derive(Diagnostic)]
#[diag("expected an associated value")]
pub(crate) struct AssociatedValueExpected {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag("found unchecked `#[rustc_clean]` attribute")]
pub(crate) struct UncheckedClean {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag("unable to delete old {$name} at `{$path}`: {$err}")]
pub(crate) struct DeleteOld<'a> {

View file

@ -19,26 +19,22 @@
//! Errors are reported if we are in the suitable configuration but
//! the required condition is not met.
use rustc_ast::{self as ast, MetaItemInner};
use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::unord::UnordSet;
use rustc_hir::attrs::{AttributeKind, RustcCleanAttribute};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{
Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, intravisit,
Attribute, ImplItemKind, ItemKind as HirItem, Node as HirNode, TraitItemKind, find_attr,
intravisit,
};
use rustc_middle::dep_graph::{DepNode, DepNodeExt, dep_kind_from_label, label_strs};
use rustc_middle::hir::nested_filter;
use rustc_middle::ty::TyCtxt;
use rustc_span::{Span, Symbol, sym};
use thin_vec::ThinVec;
use rustc_span::{Span, Symbol};
use tracing::debug;
use crate::errors;
const LOADED_FROM_DISK: Symbol = sym::loaded_from_disk;
const EXCEPT: Symbol = sym::except;
const CFG: Symbol = sym::cfg;
// Base and Extra labels to build up the labels
/// For typedef, constants, and statics
@ -127,14 +123,14 @@ const LABELS_ADT: &[&[&str]] = &[BASE_HIR, BASE_STRUCT];
type Labels = UnordSet<String>;
/// Represents the requested configuration by rustc_clean/dirty
/// Represents the requested configuration by rustc_clean
struct Assertion {
clean: Labels,
dirty: Labels,
loaded_from_disk: Labels,
}
pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
pub(crate) fn check_clean_annotations(tcx: TyCtxt<'_>) {
if !tcx.sess.opts.unstable_opts.query_dep_graph {
return;
}
@ -145,24 +141,24 @@ pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
}
tcx.dep_graph.with_ignore(|| {
let mut dirty_clean_visitor = DirtyCleanVisitor { tcx, checked_attrs: Default::default() };
let mut clean_visitor = CleanVisitor { tcx, checked_attrs: Default::default() };
let crate_items = tcx.hir_crate_items(());
for id in crate_items.free_items() {
dirty_clean_visitor.check_item(id.owner_id.def_id);
clean_visitor.check_item(id.owner_id.def_id);
}
for id in crate_items.trait_items() {
dirty_clean_visitor.check_item(id.owner_id.def_id);
clean_visitor.check_item(id.owner_id.def_id);
}
for id in crate_items.impl_items() {
dirty_clean_visitor.check_item(id.owner_id.def_id);
clean_visitor.check_item(id.owner_id.def_id);
}
for id in crate_items.foreign_items() {
dirty_clean_visitor.check_item(id.owner_id.def_id);
clean_visitor.check_item(id.owner_id.def_id);
}
let mut all_attrs = FindAllAttrs { tcx, found_attrs: vec![] };
@ -171,67 +167,62 @@ pub(crate) fn check_dirty_clean_annotations(tcx: TyCtxt<'_>) {
// Note that we cannot use the existing "unused attribute"-infrastructure
// here, since that is running before codegen. This is also the reason why
// all codegen-specific attributes are `AssumedUsed` in rustc_ast::feature_gate.
all_attrs.report_unchecked_attrs(dirty_clean_visitor.checked_attrs);
all_attrs.report_unchecked_attrs(clean_visitor.checked_attrs);
})
}
struct DirtyCleanVisitor<'tcx> {
struct CleanVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
checked_attrs: FxHashSet<ast::AttrId>,
checked_attrs: FxHashSet<Span>,
}
impl<'tcx> DirtyCleanVisitor<'tcx> {
/// Possibly "deserialize" the attribute into a clean/dirty assertion
fn assertion_maybe(&mut self, item_id: LocalDefId, attr: &Attribute) -> Option<Assertion> {
assert!(attr.has_name(sym::rustc_clean));
if !check_config(self.tcx, attr) {
// skip: not the correct `cfg=`
return None;
}
let assertion = self.assertion_auto(item_id, attr);
Some(assertion)
impl<'tcx> CleanVisitor<'tcx> {
/// Convert the attribute to an [`Assertion`] if the relevant cfg is active
fn assertion_maybe(
&mut self,
item_id: LocalDefId,
attr: &RustcCleanAttribute,
) -> Option<Assertion> {
self.tcx
.sess
.psess
.config
.contains(&(attr.cfg, None))
.then(|| self.assertion_auto(item_id, attr))
}
/// Gets the "auto" assertion on pre-validated attr, along with the `except` labels.
fn assertion_auto(&mut self, item_id: LocalDefId, attr: &Attribute) -> Assertion {
let (name, mut auto) = self.auto_labels(item_id, attr);
fn assertion_auto(&mut self, item_id: LocalDefId, attr: &RustcCleanAttribute) -> Assertion {
let (name, mut auto) = self.auto_labels(item_id, attr.span);
let except = self.except(attr);
let loaded_from_disk = self.loaded_from_disk(attr);
for e in except.items().into_sorted_stable_ord() {
if !auto.remove(e) {
self.tcx.dcx().emit_fatal(errors::AssertionAuto { span: attr.span(), name, e });
self.tcx.dcx().emit_fatal(errors::AssertionAuto { span: attr.span, name, e });
}
}
Assertion { clean: auto, dirty: except, loaded_from_disk }
}
/// `loaded_from_disk=` attribute value
fn loaded_from_disk(&self, attr: &Attribute) -> Labels {
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
if item.has_name(LOADED_FROM_DISK) {
let value = expect_associated_value(self.tcx, &item);
return self.resolve_labels(&item, value);
}
}
// If `loaded_from_disk=` is not specified, don't assert anything
Labels::default()
fn loaded_from_disk(&self, attr: &RustcCleanAttribute) -> Labels {
attr.loaded_from_disk
.as_ref()
.map(|queries| self.resolve_labels(&queries.entries, queries.span))
.unwrap_or_default()
}
/// `except=` attribute value
fn except(&self, attr: &Attribute) -> Labels {
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
if item.has_name(EXCEPT) {
let value = expect_associated_value(self.tcx, &item);
return self.resolve_labels(&item, value);
}
}
// if no `label` or `except` is given, only the node's group are asserted
Labels::default()
fn except(&self, attr: &RustcCleanAttribute) -> Labels {
attr.except
.as_ref()
.map(|queries| self.resolve_labels(&queries.entries, queries.span))
.unwrap_or_default()
}
/// Return all DepNode labels that should be asserted for this item.
/// index=0 is the "name" used for error messages
fn auto_labels(&mut self, item_id: LocalDefId, attr: &Attribute) -> (&'static str, Labels) {
fn auto_labels(&mut self, item_id: LocalDefId, span: Span) -> (&'static str, Labels) {
let node = self.tcx.hir_node_by_def_id(item_id);
let (name, labels) = match node {
HirNode::Item(item) => {
@ -282,7 +273,7 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL),
_ => self.tcx.dcx().emit_fatal(errors::UndefinedCleanDirtyItem {
span: attr.span(),
span,
kind: format!("{:?}", item.kind),
}),
}
@ -297,31 +288,31 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
ImplItemKind::Const(..) => ("NodeImplConst", LABELS_CONST_IN_IMPL),
ImplItemKind::Type(..) => ("NodeImplType", LABELS_CONST_IN_IMPL),
},
_ => self.tcx.dcx().emit_fatal(errors::UndefinedCleanDirty {
span: attr.span(),
kind: format!("{node:?}"),
}),
_ => self
.tcx
.dcx()
.emit_fatal(errors::UndefinedCleanDirty { span, kind: format!("{node:?}") }),
};
let labels =
Labels::from_iter(labels.iter().flat_map(|s| s.iter().map(|l| (*l).to_string())));
(name, labels)
}
fn resolve_labels(&self, item: &MetaItemInner, value: Symbol) -> Labels {
fn resolve_labels(&self, values: &[Symbol], span: Span) -> Labels {
let mut out = Labels::default();
for label in value.as_str().split(',') {
let label = label.trim();
if DepNode::has_label_string(label) {
if out.contains(label) {
for label in values {
let label_str = label.as_str();
if DepNode::has_label_string(label_str) {
if out.contains(label_str) {
self.tcx
.dcx()
.emit_fatal(errors::RepeatedDepNodeLabel { span: item.span(), label });
.emit_fatal(errors::RepeatedDepNodeLabel { span, label: label_str });
}
out.insert(label.to_string());
out.insert(label_str.to_string());
} else {
self.tcx
.dcx()
.emit_fatal(errors::UnrecognizedDepNodeLabel { span: item.span(), label });
.emit_fatal(errors::UnrecognizedDepNodeLabel { span, label: label_str });
}
}
out
@ -360,11 +351,18 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
fn check_item(&mut self, item_id: LocalDefId) {
let item_span = self.tcx.def_span(item_id.to_def_id());
let def_path_hash = self.tcx.def_path_hash(item_id.to_def_id());
for attr in self.tcx.get_attrs(item_id, sym::rustc_clean) {
let Some(attr) =
find_attr!(self.tcx.get_all_attrs(item_id), AttributeKind::RustcClean(attr) => attr)
else {
return;
};
for attr in attr {
let Some(assertion) = self.assertion_maybe(item_id, attr) else {
continue;
};
self.checked_attrs.insert(attr.id());
self.checked_attrs.insert(attr.span);
for label in assertion.clean.items().into_sorted_stable_ord() {
let dep_node = DepNode::from_label_string(self.tcx, label, def_path_hash).unwrap();
self.assert_clean(item_span, dep_node);
@ -400,61 +398,24 @@ impl<'tcx> DirtyCleanVisitor<'tcx> {
}
}
/// Given a `#[rustc_clean]` attribute, scan for a `cfg="foo"` attribute and check whether we have
/// a cfg flag called `foo`.
fn check_config(tcx: TyCtxt<'_>, attr: &Attribute) -> bool {
debug!("check_config(attr={:?})", attr);
let config = &tcx.sess.psess.config;
debug!("check_config: config={:?}", config);
let mut cfg = None;
for item in attr.meta_item_list().unwrap_or_else(ThinVec::new) {
if item.has_name(CFG) {
let value = expect_associated_value(tcx, &item);
debug!("check_config: searching for cfg {:?}", value);
cfg = Some(config.contains(&(value, None)));
} else if !(item.has_name(EXCEPT) || item.has_name(LOADED_FROM_DISK)) {
tcx.dcx().emit_err(errors::UnknownRustcCleanArgument { span: item.span() });
}
}
match cfg {
None => tcx.dcx().emit_fatal(errors::NoCfg { span: attr.span() }),
Some(c) => c,
}
}
fn expect_associated_value(tcx: TyCtxt<'_>, item: &MetaItemInner) -> Symbol {
if let Some(value) = item.value_str() {
value
} else if let Some(ident) = item.ident() {
tcx.dcx().emit_fatal(errors::AssociatedValueExpectedFor { span: item.span(), ident });
} else {
tcx.dcx().emit_fatal(errors::AssociatedValueExpected { span: item.span() });
}
}
/// A visitor that collects all `#[rustc_clean]` attributes from
/// the HIR. It is used to verify that we really ran checks for all annotated
/// nodes.
struct FindAllAttrs<'tcx> {
tcx: TyCtxt<'tcx>,
found_attrs: Vec<&'tcx Attribute>,
found_attrs: Vec<&'tcx RustcCleanAttribute>,
}
impl<'tcx> FindAllAttrs<'tcx> {
fn is_active_attr(&mut self, attr: &Attribute) -> bool {
if attr.has_name(sym::rustc_clean) && check_config(self.tcx, attr) {
return true;
}
false
fn is_active_attr(&self, attr: &RustcCleanAttribute) -> bool {
self.tcx.sess.psess.config.contains(&(attr.cfg, None))
}
fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet<ast::AttrId>) {
fn report_unchecked_attrs(&self, mut checked_attrs: FxHashSet<Span>) {
for attr in &self.found_attrs {
if !checked_attrs.contains(&attr.id()) {
self.tcx.dcx().emit_err(errors::UncheckedClean { span: attr.span() });
checked_attrs.insert(attr.id());
if !checked_attrs.contains(&attr.span) {
self.tcx.dcx().emit_err(errors::UncheckedClean { span: attr.span });
checked_attrs.insert(attr.span);
}
}
}
@ -468,8 +429,12 @@ impl<'tcx> intravisit::Visitor<'tcx> for FindAllAttrs<'tcx> {
}
fn visit_attribute(&mut self, attr: &'tcx Attribute) {
if self.is_active_attr(attr) {
self.found_attrs.push(attr);
if let Attribute::Parsed(AttributeKind::RustcClean(attrs)) = attr {
for attr in attrs {
if self.is_active_attr(attr) {
self.found_attrs.push(attr);
}
}
}
}
}

View file

@ -2,8 +2,8 @@
//! into the given directory. At the same time, it also hashes the
//! various HIR nodes.
mod clean;
mod data;
mod dirty_clean;
mod file_format;
mod fs;
mod load;

View file

@ -14,7 +14,7 @@ use tracing::debug;
use super::data::*;
use super::fs::*;
use super::{dirty_clean, file_format, work_product};
use super::{clean, file_format, work_product};
use crate::assert_dep_graph::assert_dep_graph;
use crate::errors;
@ -42,7 +42,7 @@ pub(crate) fn save_dep_graph(tcx: TyCtxt<'_>) {
let staging_dep_graph_path = staging_dep_graph_path(sess);
sess.time("assert_dep_graph", || assert_dep_graph(tcx));
sess.time("check_dirty_clean", || dirty_clean::check_dirty_clean_annotations(tcx));
sess.time("check_clean", || clean::check_clean_annotations(tcx));
join(
move || {

View file

@ -441,7 +441,14 @@ pub(super) fn rustc_queries(input: TokenStream) -> TokenStream {
$macro!(#feedable_queries);
}
}
pub mod descs {
/// Functions that format a human-readable description of each query
/// and its key, as specified by the `desc` query modifier.
///
/// (The leading `_` avoids collisions with actual query names when
/// expanded in `rustc_middle::queries`, and makes this macro-generated
/// module easier to search for.)
pub mod _description_fns {
use super::*;
#description_fns_stream
}

View file

@ -15,7 +15,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_fs_util = { path = "../rustc_fs_util" }
rustc_hir = { path = "../rustc_hir" }
rustc_hir_pretty = { path = "../rustc_hir_pretty" }

View file

@ -1,240 +0,0 @@
metadata_async_drop_types_in_dependency =
found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`
.help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
metadata_bad_panic_strategy =
the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}`
metadata_binary_output_to_tty =
option `-o` or `--emit` is used to write binary output type `metadata` to stdout, but stdout is a tty
metadata_cannot_find_crate =
can't find crate for `{$crate_name}`{$add_info}
metadata_cant_find_crate =
can't find crate
metadata_compiler_missing_profiler =
the compiler may have been built without the profiler runtime
metadata_conflicting_alloc_error_handler =
the `#[alloc_error_handler]` in {$other_crate_name} conflicts with allocation error handler in: {$crate_name}
metadata_conflicting_global_alloc =
the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name}
metadata_consider_adding_std =
consider adding the standard library to the sysroot with `x build library --target {$locator_triple}`
metadata_consider_building_std =
consider building the standard library from source with `cargo build -Zbuild-std`
metadata_consider_downloading_target =
consider downloading the target with `rustup target add {$locator_triple}`
metadata_crate_dep_multiple =
cannot satisfy dependencies so `{$crate_name}` only shows up once
.help = having upstream crates all available in one format will likely make this go away
metadata_crate_dep_not_static =
`{$crate_name}` was unavailable as a static crate, preventing fully static linking
metadata_crate_dep_rustc_driver =
`feature(rustc_private)` is needed to link to the compiler's `rustc_driver` library
metadata_crate_location_unknown_type =
extern location for {$crate_name} is of an unknown type: {$path}
metadata_crate_not_compiler_builtins =
the crate `{$crate_name}` resolved as `compiler_builtins` but is not `#![compiler_builtins]`
metadata_crate_not_panic_runtime =
the crate `{$crate_name}` is not a panic runtime
metadata_dl_error =
{$path}{$err}
metadata_empty_renaming_target =
an empty renaming target was specified for library `{$lib_name}`
metadata_extern_location_not_exist =
extern location for {$crate_name} does not exist: {$location}
metadata_extern_location_not_file =
extern location for {$crate_name} is not a file: {$location}
metadata_fail_create_file_encoder =
failed to create file encoder: {$err}
metadata_fail_write_file =
failed to write to `{$path}`: {$err}
metadata_failed_copy_to_stdout =
failed to copy {$filename} to stdout: {$err}
metadata_failed_create_encoded_metadata =
failed to create encoded metadata from file: {$err}
metadata_failed_create_file =
failed to create the file {$filename}: {$err}
metadata_failed_create_tempdir =
couldn't create a temp dir: {$err}
metadata_failed_write_error =
failed to write {$filename}: {$err}
metadata_found_crate_versions =
the following crate versions were found:{$found_crates}
metadata_found_staticlib =
found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}
.help = please recompile that crate using --crate-type lib
metadata_full_metadata_not_found =
only metadata stub found for `{$flavor}` dependency `{$crate_name}`
please provide path to the corresponding .rmeta file with full metadata
metadata_global_alloc_required =
no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait
metadata_incompatible_panic_in_drop_strategy =
the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
metadata_incompatible_rustc =
found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}
.help = please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)
metadata_incompatible_target_modifiers =
mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
.note = `{$flag_name_prefixed}={$local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`
.help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
metadata_incompatible_target_modifiers_help_allow = if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error
metadata_incompatible_target_modifiers_help_fix = set `{$flag_name_prefixed}={$extern_value}` in this crate or `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`
metadata_incompatible_target_modifiers_help_fix_l_missed = set `{$flag_name_prefixed}={$extern_value}` in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}`
metadata_incompatible_target_modifiers_help_fix_r_missed = unset `{$flag_name_prefixed}` in this crate or set `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`
metadata_incompatible_target_modifiers_l_missed =
mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
.note = unset `{$flag_name_prefixed}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`
.help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
metadata_incompatible_target_modifiers_r_missed =
mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`
.note = `{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}`
.help = the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
metadata_incompatible_with_immediate_abort =
the crate `{$crate_name}` was compiled with a panic strategy which is incompatible with `immediate-abort`
metadata_incompatible_with_immediate_abort_core =
the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`
.help = consider building the standard library from source with `cargo build -Zbuild-std`
metadata_install_missing_components =
maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`
metadata_invalid_meta_files =
found invalid metadata files for crate `{$crate_name}`{$add_info}
metadata_lib_filename_form =
file name should be lib*.rlib or {$dll_prefix}*{$dll_suffix}
metadata_lib_framework_apple =
library kind `framework` is only supported on Apple targets
metadata_lib_required =
crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form
metadata_link_ordinal_raw_dylib =
`#[link_ordinal]` is only supported if link kind is `raw-dylib`
metadata_missing_native_library =
could not find native static library `{$libname}`, perhaps an -L flag is missing?
metadata_multiple_candidates =
multiple candidates for `{$flavor}` dependency `{$crate_name}` found
metadata_multiple_renamings =
multiple renamings were specified for library `{$lib_name}`
metadata_newer_crate_version =
found possibly newer version of crate `{$crate_name}`{$add_info}
.note = perhaps that crate needs to be recompiled?
metadata_no_crate_with_triple =
couldn't find crate `{$crate_name}` with expected target triple {$locator_triple}{$add_info}
metadata_no_link_mod_override =
overriding linking modifiers from command line is not supported
metadata_no_multiple_alloc_error_handler =
cannot define multiple allocation error handlers
.label = cannot define a new allocation error handler
metadata_no_multiple_global_alloc =
cannot define multiple global allocators
.label = cannot define a new global allocator
metadata_no_panic_strategy =
the crate `{$crate_name}` does not have the panic strategy `{$strategy}`
metadata_no_transitive_needs_dep =
the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}`
metadata_non_ascii_name =
cannot load a crate with a non-ascii name `{$crate_name}`
metadata_not_profiler_runtime =
the crate `{$crate_name}` is not a profiler runtime
metadata_only_provide_library_name = only provide the library name `{$suggested_name}`, not the full filename
metadata_prev_alloc_error_handler =
previous allocation error handler defined here
metadata_prev_global_alloc =
previous global allocator defined here
metadata_raw_dylib_malformed =
link name must be well-formed if link kind is `raw-dylib`
metadata_raw_dylib_unsupported_abi =
ABI not supported by `#[link(kind = "raw-dylib")]` on this architecture
metadata_renaming_no_link =
renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library
metadata_required_panic_strategy =
the crate `{$crate_name}` requires panic strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`
metadata_rlib_required =
crate `{$crate_name}` required to be available in rlib format, but was not found in this form
metadata_rustc_lib_required =
crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form
.note = only .rmeta files are distributed for `rustc_private` crates other than `rustc_driver`
.help = try adding `extern crate rustc_driver;` at the top level of this crate
metadata_stable_crate_id_collision =
found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values
metadata_std_required =
`std` is required by `{$current_crate}` because it does not declare `#![no_std]`
metadata_symbol_conflicts_current =
the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments, so this will result in symbol conflicts between the two
metadata_target_no_std_support =
the `{$locator_triple}` target may not support the standard library
metadata_target_not_installed =
the `{$locator_triple}` target may not be installed
metadata_two_panic_runtimes =
cannot link together two panic runtimes: {$prev_name} and {$cur_name}
metadata_unknown_target_modifier_unsafe_allowed = unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`
metadata_wasm_c_abi =
older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88

View file

@ -2,38 +2,43 @@ use std::io::Error;
use std::path::{Path, PathBuf};
use rustc_errors::codes::*;
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level};
use rustc_errors::{Diag, DiagCtxtHandle, Diagnostic, EmissionGuarantee, Level, inline_fluent};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol, sym};
use rustc_target::spec::{PanicStrategy, TargetTuple};
use crate::fluent_generated as fluent;
use crate::locator::CrateFlavor;
#[derive(Diagnostic)]
#[diag(metadata_rlib_required)]
#[diag(
"crate `{$crate_name}` required to be available in rlib format, but was not found in this form"
)]
pub struct RlibRequired {
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_lib_required)]
#[diag(
"crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form"
)]
pub struct LibRequired<'a> {
pub crate_name: Symbol,
pub kind: &'a str,
}
#[derive(Diagnostic)]
#[diag(metadata_rustc_lib_required)]
#[help]
#[diag(
"crate `{$crate_name}` required to be available in {$kind} format, but was not found in this form"
)]
#[help("try adding `extern crate rustc_driver;` at the top level of this crate")]
pub struct RustcLibRequired<'a> {
pub crate_name: Symbol,
pub kind: &'a str,
}
#[derive(Diagnostic)]
#[diag(metadata_crate_dep_multiple)]
#[help]
#[diag("cannot satisfy dependencies so `{$crate_name}` only shows up once")]
#[help("having upstream crates all available in one format will likely make this go away")]
pub struct CrateDepMultiple {
pub crate_name: Symbol,
#[subdiagnostic]
@ -43,32 +48,36 @@ pub struct CrateDepMultiple {
}
#[derive(Subdiagnostic)]
#[note(metadata_crate_dep_not_static)]
#[note("`{$crate_name}` was unavailable as a static crate, preventing fully static linking")]
pub struct NonStaticCrateDep {
/// It's different from `crate_name` in main Diagnostic.
pub crate_name_: Symbol,
}
#[derive(Subdiagnostic)]
#[help(metadata_crate_dep_rustc_driver)]
#[help("`feature(rustc_private)` is needed to link to the compiler's `rustc_driver` library")]
pub struct RustcDriverHelp;
#[derive(Diagnostic)]
#[diag(metadata_two_panic_runtimes)]
#[diag("cannot link together two panic runtimes: {$prev_name} and {$cur_name}")]
pub struct TwoPanicRuntimes {
pub prev_name: Symbol,
pub cur_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_bad_panic_strategy)]
#[diag(
"the linked panic runtime `{$runtime}` is not compiled with this crate's panic strategy `{$strategy}`"
)]
pub struct BadPanicStrategy {
pub runtime: Symbol,
pub strategy: PanicStrategy,
}
#[derive(Diagnostic)]
#[diag(metadata_required_panic_strategy)]
#[diag(
"the crate `{$crate_name}` requires panic strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`"
)]
pub struct RequiredPanicStrategy {
pub crate_name: Symbol,
pub found_strategy: PanicStrategy,
@ -76,17 +85,23 @@ pub struct RequiredPanicStrategy {
}
#[derive(Diagnostic)]
#[diag(metadata_incompatible_with_immediate_abort)]
#[diag(
"the crate `{$crate_name}` was compiled with a panic strategy which is incompatible with `immediate-abort`"
)]
pub struct IncompatibleWithImmediateAbort {
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_incompatible_with_immediate_abort_core)]
#[diag(
"the crate `core` was compiled with a panic strategy which is incompatible with `immediate-abort`"
)]
pub struct IncompatibleWithImmediateAbortCore;
#[derive(Diagnostic)]
#[diag(metadata_incompatible_panic_in_drop_strategy)]
#[diag(
"the crate `{$crate_name}` is compiled with the panic-in-drop strategy `{$found_strategy}` which is incompatible with this crate's strategy of `{$desired_strategy}`"
)]
pub struct IncompatiblePanicInDropStrategy {
pub crate_name: Symbol,
pub found_strategy: PanicStrategy,
@ -94,126 +109,138 @@ pub struct IncompatiblePanicInDropStrategy {
}
#[derive(Diagnostic)]
#[diag(metadata_link_ordinal_raw_dylib)]
#[diag("`#[link_ordinal]` is only supported if link kind is `raw-dylib`")]
pub struct LinkOrdinalRawDylib {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(metadata_lib_framework_apple)]
#[diag("library kind `framework` is only supported on Apple targets")]
pub struct LibFrameworkApple;
#[derive(Diagnostic)]
#[diag(metadata_empty_renaming_target)]
#[diag("an empty renaming target was specified for library `{$lib_name}`")]
pub struct EmptyRenamingTarget<'a> {
pub lib_name: &'a str,
}
#[derive(Diagnostic)]
#[diag(metadata_renaming_no_link)]
#[diag(
"renaming of the library `{$lib_name}` was specified, however this crate contains no `#[link(...)]` attributes referencing this library"
)]
pub struct RenamingNoLink<'a> {
pub lib_name: &'a str,
}
#[derive(Diagnostic)]
#[diag(metadata_multiple_renamings)]
#[diag("multiple renamings were specified for library `{$lib_name}`")]
pub struct MultipleRenamings<'a> {
pub lib_name: &'a str,
}
#[derive(Diagnostic)]
#[diag(metadata_no_link_mod_override)]
#[diag("overriding linking modifiers from command line is not supported")]
pub struct NoLinkModOverride {
#[primary_span]
pub span: Option<Span>,
}
#[derive(Diagnostic)]
#[diag(metadata_raw_dylib_unsupported_abi)]
#[diag("ABI not supported by `#[link(kind = \"raw-dylib\")]` on this architecture")]
pub struct RawDylibUnsupportedAbi {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(metadata_fail_create_file_encoder)]
#[diag("failed to create file encoder: {$err}")]
pub struct FailCreateFileEncoder {
pub err: Error,
}
#[derive(Diagnostic)]
#[diag(metadata_fail_write_file)]
#[diag("failed to write to `{$path}`: {$err}")]
pub struct FailWriteFile<'a> {
pub path: &'a Path,
pub err: Error,
}
#[derive(Diagnostic)]
#[diag(metadata_crate_not_panic_runtime)]
#[diag("the crate `{$crate_name}` is not a panic runtime")]
pub struct CrateNotPanicRuntime {
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_crate_not_compiler_builtins)]
#[diag(
"the crate `{$crate_name}` resolved as `compiler_builtins` but is not `#![compiler_builtins]`"
)]
pub struct CrateNotCompilerBuiltins {
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_no_panic_strategy)]
#[diag("the crate `{$crate_name}` does not have the panic strategy `{$strategy}`")]
pub struct NoPanicStrategy {
pub crate_name: Symbol,
pub strategy: PanicStrategy,
}
#[derive(Diagnostic)]
#[diag(metadata_not_profiler_runtime)]
#[diag("the crate `{$crate_name}` is not a profiler runtime")]
pub struct NotProfilerRuntime {
pub crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_no_multiple_global_alloc)]
#[diag("cannot define multiple global allocators")]
pub struct NoMultipleGlobalAlloc {
#[primary_span]
#[label]
#[label("cannot define a new global allocator")]
pub span2: Span,
#[label(metadata_prev_global_alloc)]
#[label("previous global allocator defined here")]
pub span1: Span,
}
#[derive(Diagnostic)]
#[diag(metadata_no_multiple_alloc_error_handler)]
#[diag("cannot define multiple allocation error handlers")]
pub struct NoMultipleAllocErrorHandler {
#[primary_span]
#[label]
#[label("cannot define a new allocation error handler")]
pub span2: Span,
#[label(metadata_prev_alloc_error_handler)]
#[label("previous allocation error handler defined here")]
pub span1: Span,
}
#[derive(Diagnostic)]
#[diag(metadata_conflicting_global_alloc)]
#[diag(
"the `#[global_allocator]` in {$other_crate_name} conflicts with global allocator in: {$crate_name}"
)]
pub struct ConflictingGlobalAlloc {
pub crate_name: Symbol,
pub other_crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_conflicting_alloc_error_handler)]
#[diag(
"the `#[alloc_error_handler]` in {$other_crate_name} conflicts with allocation error handler in: {$crate_name}"
)]
pub struct ConflictingAllocErrorHandler {
pub crate_name: Symbol,
pub other_crate_name: Symbol,
}
#[derive(Diagnostic)]
#[diag(metadata_global_alloc_required)]
#[diag(
"no global memory allocator found but one is required; link to std or add `#[global_allocator]` to a static item that implements the GlobalAlloc trait"
)]
pub struct GlobalAllocRequired;
#[derive(Diagnostic)]
#[diag(metadata_no_transitive_needs_dep)]
#[diag(
"the crate `{$crate_name}` cannot depend on a crate that needs {$needs_crate_name}, but it depends on `{$deps_crate_name}`"
)]
pub struct NoTransitiveNeedsDep<'a> {
pub crate_name: Symbol,
pub needs_crate_name: &'a str,
@ -221,25 +248,27 @@ pub struct NoTransitiveNeedsDep<'a> {
}
#[derive(Diagnostic)]
#[diag(metadata_failed_write_error)]
#[diag("failed to write {$filename}: {$err}")]
pub struct FailedWriteError {
pub filename: PathBuf,
pub err: Error,
}
#[derive(Diagnostic)]
#[diag(metadata_failed_copy_to_stdout)]
#[diag("failed to copy {$filename} to stdout: {$err}")]
pub struct FailedCopyToStdout {
pub filename: PathBuf,
pub err: Error,
}
#[derive(Diagnostic)]
#[diag(metadata_binary_output_to_tty)]
#[diag(
"option `-o` or `--emit` is used to write binary output type `metadata` to stdout, but stdout is a tty"
)]
pub struct BinaryOutputToTty;
#[derive(Diagnostic)]
#[diag(metadata_missing_native_library)]
#[diag("could not find native static library `{$libname}`, perhaps an -L flag is missing?")]
pub struct MissingNativeLibrary<'a> {
libname: &'a str,
#[subdiagnostic]
@ -273,32 +302,32 @@ impl<'a> MissingNativeLibrary<'a> {
}
#[derive(Subdiagnostic)]
#[help(metadata_only_provide_library_name)]
#[help("only provide the library name `{$suggested_name}`, not the full filename")]
pub struct SuggestLibraryName<'a> {
suggested_name: &'a str,
}
#[derive(Diagnostic)]
#[diag(metadata_failed_create_tempdir)]
#[diag("couldn't create a temp dir: {$err}")]
pub struct FailedCreateTempdir {
pub err: Error,
}
#[derive(Diagnostic)]
#[diag(metadata_failed_create_file)]
#[diag("failed to create the file {$filename}: {$err}")]
pub struct FailedCreateFile<'a> {
pub filename: &'a Path,
pub err: Error,
}
#[derive(Diagnostic)]
#[diag(metadata_failed_create_encoded_metadata)]
#[diag("failed to create encoded metadata from file: {$err}")]
pub struct FailedCreateEncodedMetadata {
pub err: Error,
}
#[derive(Diagnostic)]
#[diag(metadata_non_ascii_name)]
#[diag("cannot load a crate with a non-ascii name `{$crate_name}`")]
pub struct NonAsciiName {
#[primary_span]
pub span: Span,
@ -306,7 +335,7 @@ pub struct NonAsciiName {
}
#[derive(Diagnostic)]
#[diag(metadata_extern_location_not_exist)]
#[diag("extern location for {$crate_name} does not exist: {$location}")]
pub struct ExternLocationNotExist<'a> {
#[primary_span]
pub span: Span,
@ -315,7 +344,7 @@ pub struct ExternLocationNotExist<'a> {
}
#[derive(Diagnostic)]
#[diag(metadata_extern_location_not_file)]
#[diag("extern location for {$crate_name} is not a file: {$location}")]
pub struct ExternLocationNotFile<'a> {
#[primary_span]
pub span: Span,
@ -332,7 +361,11 @@ pub(crate) struct MultipleCandidates {
impl<G: EmissionGuarantee> Diagnostic<'_, G> for MultipleCandidates {
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::metadata_multiple_candidates);
let mut diag = Diag::new(
dcx,
level,
inline_fluent!("multiple candidates for `{$flavor}` dependency `{$crate_name}` found"),
);
diag.arg("crate_name", self.crate_name);
diag.arg("flavor", self.flavor);
diag.code(E0464);
@ -345,7 +378,9 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for MultipleCandidates {
}
#[derive(Diagnostic)]
#[diag(metadata_full_metadata_not_found)]
#[diag(
"only metadata stub found for `{$flavor}` dependency `{$crate_name}` please provide path to the corresponding .rmeta file with full metadata"
)]
pub(crate) struct FullMetadataNotFound {
#[primary_span]
pub span: Span,
@ -354,7 +389,7 @@ pub(crate) struct FullMetadataNotFound {
}
#[derive(Diagnostic)]
#[diag(metadata_symbol_conflicts_current, code = E0519)]
#[diag("the current crate is indistinguishable from one of its dependencies: it has the same crate-name `{$crate_name}` and was compiled with the same `-C metadata` arguments, so this will result in symbol conflicts between the two", code = E0519)]
pub struct SymbolConflictsCurrent {
#[primary_span]
pub span: Span,
@ -362,7 +397,7 @@ pub struct SymbolConflictsCurrent {
}
#[derive(Diagnostic)]
#[diag(metadata_stable_crate_id_collision)]
#[diag("found crates (`{$crate_name0}` and `{$crate_name1}`) with colliding StableCrateId values")]
pub struct StableCrateIdCollision {
#[primary_span]
pub span: Span,
@ -371,7 +406,7 @@ pub struct StableCrateIdCollision {
}
#[derive(Diagnostic)]
#[diag(metadata_dl_error)]
#[diag("{$path}{$err}")]
pub struct DlError {
#[primary_span]
pub span: Span,
@ -380,9 +415,9 @@ pub struct DlError {
}
#[derive(Diagnostic)]
#[diag(metadata_newer_crate_version, code = E0460)]
#[note]
#[note(metadata_found_crate_versions)]
#[diag("found possibly newer version of crate `{$crate_name}`{$add_info}", code = E0460)]
#[note("perhaps that crate needs to be recompiled?")]
#[note("the following crate versions were found:{$found_crates}")]
pub struct NewerCrateVersion {
#[primary_span]
pub span: Span,
@ -392,8 +427,8 @@ pub struct NewerCrateVersion {
}
#[derive(Diagnostic)]
#[diag(metadata_no_crate_with_triple, code = E0461)]
#[note(metadata_found_crate_versions)]
#[diag("couldn't find crate `{$crate_name}` with expected target triple {$locator_triple}{$add_info}", code = E0461)]
#[note("the following crate versions were found:{$found_crates}")]
pub struct NoCrateWithTriple<'a> {
#[primary_span]
pub span: Span,
@ -404,9 +439,9 @@ pub struct NoCrateWithTriple<'a> {
}
#[derive(Diagnostic)]
#[diag(metadata_found_staticlib, code = E0462)]
#[note(metadata_found_crate_versions)]
#[help]
#[diag("found staticlib `{$crate_name}` instead of rlib or dylib{$add_info}", code = E0462)]
#[note("the following crate versions were found:{$found_crates}")]
#[help("please recompile that crate using --crate-type lib")]
pub struct FoundStaticlib {
#[primary_span]
pub span: Span,
@ -416,9 +451,11 @@ pub struct FoundStaticlib {
}
#[derive(Diagnostic)]
#[diag(metadata_incompatible_rustc, code = E0514)]
#[note(metadata_found_crate_versions)]
#[help]
#[diag("found crate `{$crate_name}` compiled by an incompatible version of rustc{$add_info}", code = E0514)]
#[note("the following crate versions were found:{$found_crates}")]
#[help(
"please recompile that crate using this compiler ({$rustc_version}) (consider running `cargo clean` first)"
)]
pub struct IncompatibleRustc {
#[primary_span]
pub span: Span,
@ -438,7 +475,11 @@ pub struct InvalidMetadataFiles {
impl<G: EmissionGuarantee> Diagnostic<'_, G> for InvalidMetadataFiles {
#[track_caller]
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::metadata_invalid_meta_files);
let mut diag = Diag::new(
dcx,
level,
inline_fluent!("found invalid metadata files for crate `{$crate_name}`{$add_info}"),
);
diag.arg("crate_name", self.crate_name);
diag.arg("add_info", self.add_info);
diag.code(E0786);
@ -466,7 +507,11 @@ pub struct CannotFindCrate {
impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
#[track_caller]
fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
let mut diag = Diag::new(dcx, level, fluent::metadata_cannot_find_crate);
let mut diag = Diag::new(
dcx,
level,
inline_fluent!("can't find crate for `{$crate_name}`{$add_info}"),
);
diag.arg("crate_name", self.crate_name);
diag.arg("current_crate", self.current_crate);
diag.arg("add_info", self.add_info);
@ -475,9 +520,11 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
diag.span(self.span);
if self.crate_name == sym::std || self.crate_name == sym::core {
if self.missing_core {
diag.note(fluent::metadata_target_not_installed);
diag.note(inline_fluent!("the `{$locator_triple}` target may not be installed"));
} else {
diag.note(fluent::metadata_target_no_std_support);
diag.note(inline_fluent!(
"the `{$locator_triple}` target may not support the standard library"
));
}
let has_precompiled_std = !self.is_tier_3;
@ -485,12 +532,14 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
if self.missing_core {
if env!("CFG_RELEASE_CHANNEL") == "dev" && !self.is_ui_testing {
// Note: Emits the nicer suggestion only for the dev channel.
diag.help(fluent::metadata_consider_adding_std);
diag.help(inline_fluent!("consider adding the standard library to the sysroot with `x build library --target {$locator_triple}`"));
} else if has_precompiled_std {
// NOTE: this suggests using rustup, even though the user may not have it installed.
// That's because they could choose to install it; or this may give them a hint which
// target they need to install from their distro.
diag.help(fluent::metadata_consider_downloading_target);
diag.help(inline_fluent!(
"consider downloading the target with `rustup target add {$locator_triple}`"
));
}
}
@ -499,25 +548,27 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for CannotFindCrate {
// If it's not a dummy, that means someone added `extern crate std` explicitly and
// `#![no_std]` won't help.
if !self.missing_core && self.span.is_dummy() {
diag.note(fluent::metadata_std_required);
diag.note(inline_fluent!("`std` is required by `{$current_crate}` because it does not declare `#![no_std]`"));
}
// Recommend -Zbuild-std even on stable builds for Tier 3 targets because
// it's the recommended way to use the target, the user should switch to nightly.
if self.is_nightly_build || !has_precompiled_std {
diag.help(fluent::metadata_consider_building_std);
diag.help(inline_fluent!("consider building the standard library from source with `cargo build -Zbuild-std`"));
}
} else if self.crate_name == self.profiler_runtime {
diag.note(fluent::metadata_compiler_missing_profiler);
diag.note(inline_fluent!(
"the compiler may have been built without the profiler runtime"
));
} else if self.crate_name.as_str().starts_with("rustc_") {
diag.help(fluent::metadata_install_missing_components);
diag.help(inline_fluent!("maybe you need to install the missing components with: `rustup component add rust-src rustc-dev llvm-tools-preview`"));
}
diag.span_label(self.span, fluent::metadata_cant_find_crate);
diag.span_label(self.span, inline_fluent!("can't find crate"));
diag
}
}
#[derive(Diagnostic)]
#[diag(metadata_crate_location_unknown_type)]
#[diag("extern location for {$crate_name} is of an unknown type: {$path}")]
pub struct CrateLocationUnknownType<'a> {
#[primary_span]
pub span: Span,
@ -526,7 +577,7 @@ pub struct CrateLocationUnknownType<'a> {
}
#[derive(Diagnostic)]
#[diag(metadata_lib_filename_form)]
#[diag("file name should be lib*.rlib or {$dll_prefix}*{$dll_suffix}")]
pub struct LibFilenameForm<'a> {
#[primary_span]
pub span: Span,
@ -535,18 +586,28 @@ pub struct LibFilenameForm<'a> {
}
#[derive(Diagnostic)]
#[diag(metadata_wasm_c_abi)]
#[diag(
"older versions of the `wasm-bindgen` crate are incompatible with current versions of Rust; please update to `wasm-bindgen` v0.2.88"
)]
pub(crate) struct WasmCAbi {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(metadata_incompatible_target_modifiers)]
#[help]
#[note]
#[help(metadata_incompatible_target_modifiers_help_fix)]
#[help(metadata_incompatible_target_modifiers_help_allow)]
#[diag("mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`")]
#[help(
"the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely"
)]
#[note(
"`{$flag_name_prefixed}={$local_value}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`"
)]
#[help(
"set `{$flag_name_prefixed}={$extern_value}` in this crate or `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`"
)]
#[help(
"if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error"
)]
pub struct IncompatibleTargetModifiers {
#[primary_span]
pub span: Span,
@ -559,11 +620,19 @@ pub struct IncompatibleTargetModifiers {
}
#[derive(Diagnostic)]
#[diag(metadata_incompatible_target_modifiers_l_missed)]
#[help]
#[note]
#[help(metadata_incompatible_target_modifiers_help_fix_l_missed)]
#[help(metadata_incompatible_target_modifiers_help_allow)]
#[diag("mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`")]
#[help(
"the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely"
)]
#[note(
"unset `{$flag_name_prefixed}` in this crate is incompatible with `{$flag_name_prefixed}={$extern_value}` in dependency `{$extern_crate}`"
)]
#[help(
"set `{$flag_name_prefixed}={$extern_value}` in this crate or unset `{$flag_name_prefixed}` in `{$extern_crate}`"
)]
#[help(
"if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error"
)]
pub struct IncompatibleTargetModifiersLMissed {
#[primary_span]
pub span: Span,
@ -575,11 +644,19 @@ pub struct IncompatibleTargetModifiersLMissed {
}
#[derive(Diagnostic)]
#[diag(metadata_incompatible_target_modifiers_r_missed)]
#[help]
#[note]
#[help(metadata_incompatible_target_modifiers_help_fix_r_missed)]
#[help(metadata_incompatible_target_modifiers_help_allow)]
#[diag("mixing `{$flag_name_prefixed}` will cause an ABI mismatch in crate `{$local_crate}`")]
#[help(
"the `{$flag_name_prefixed}` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely"
)]
#[note(
"`{$flag_name_prefixed}={$local_value}` in this crate is incompatible with unset `{$flag_name_prefixed}` in dependency `{$extern_crate}`"
)]
#[help(
"unset `{$flag_name_prefixed}` in this crate or set `{$flag_name_prefixed}={$local_value}` in `{$extern_crate}`"
)]
#[help(
"if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch={$flag_name}` to silence this error"
)]
pub struct IncompatibleTargetModifiersRMissed {
#[primary_span]
pub span: Span,
@ -591,7 +668,9 @@ pub struct IncompatibleTargetModifiersRMissed {
}
#[derive(Diagnostic)]
#[diag(metadata_unknown_target_modifier_unsafe_allowed)]
#[diag(
"unknown target modifier `{$flag_name}`, requested by `-Cunsafe-allow-abi-mismatch={$flag_name}`"
)]
pub struct UnknownTargetModifierUnsafeAllowed {
#[primary_span]
pub span: Span,
@ -599,8 +678,12 @@ pub struct UnknownTargetModifierUnsafeAllowed {
}
#[derive(Diagnostic)]
#[diag(metadata_async_drop_types_in_dependency)]
#[help]
#[diag(
"found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`"
)]
#[help(
"if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used"
)]
pub struct AsyncDropTypesInDependency {
#[primary_span]
pub span: Span,
@ -609,7 +692,7 @@ pub struct AsyncDropTypesInDependency {
}
#[derive(Diagnostic)]
#[diag(metadata_raw_dylib_malformed)]
#[diag("link name must be well-formed if link kind is `raw-dylib`")]
pub struct RawDylibMalformed {
#[primary_span]
pub span: Span,

View file

@ -34,5 +34,3 @@ pub use native_libs::{
try_find_native_static_library, walk_native_lib_search_dirs,
};
pub use rmeta::{EncodedMetadata, METADATA_HEADER, encode_metadata, rendered_const};
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -1298,10 +1298,6 @@ impl<'a> CrateMetadataRef<'a> {
}
}
fn is_ctfe_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool {
self.root.tables.mir_for_ctfe.get((self, tcx), id).is_some()
}
fn is_item_mir_available(self, tcx: TyCtxt<'_>, id: DefIndex) -> bool {
self.root.tables.optimized_mir.get((self, tcx), id).is_some()
}

View file

@ -324,7 +324,6 @@ provide! { tcx, def_id, other, cdata,
inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) }
attrs_for_def => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(tcx, def_id.index)) }
is_mir_available => { cdata.is_item_mir_available(tcx, def_id.index) }
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(tcx, def_id.index) }
cross_crate_inlinable => { table_direct }
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }

View file

@ -1102,12 +1102,8 @@ fn should_encode_mir(
def_id: LocalDefId,
) -> (bool, bool) {
match tcx.def_kind(def_id) {
// Constructors
DefKind::Ctor(_, _) => {
let mir_opt_base = tcx.sess.opts.output_types.should_codegen()
|| tcx.sess.opts.unstable_opts.always_encode_mir;
(true, mir_opt_base)
}
// instance_mir uses mir_for_ctfe rather than optimized_mir for constructors
DefKind::Ctor(_, _) => (true, false),
// Constants
DefKind::AnonConst | DefKind::InlineConst | DefKind::AssocConst | DefKind::Const => {
(true, false)
@ -1117,11 +1113,10 @@ fn should_encode_mir(
DefKind::SyntheticCoroutineBody => (false, true),
// Full-fledged functions + closures
DefKind::AssocFn | DefKind::Fn | DefKind::Closure => {
let generics = tcx.generics_of(def_id);
let opt = tcx.sess.opts.unstable_opts.always_encode_mir
|| (tcx.sess.opts.output_types.should_codegen()
&& reachable_set.contains(&def_id)
&& (generics.requires_monomorphization(tcx)
&& (tcx.generics_of(def_id).requires_monomorphization(tcx)
|| tcx.cross_crate_inlinable(def_id)));
// The function has a `const` modifier or is in a `const trait`.
let is_const_fn = tcx.is_const_fn(def_id.to_def_id());

View file

@ -18,7 +18,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_graphviz = { path = "../rustc_graphviz" }
rustc_hashes = { path = "../rustc_hashes" }
rustc_hir = { path = "../rustc_hir" }

View file

@ -1,133 +0,0 @@
middle_assert_async_resume_after_drop = `async fn` resumed after async drop
middle_assert_async_resume_after_panic = `async fn` resumed after panicking
middle_assert_async_resume_after_return = `async fn` resumed after completion
middle_assert_coroutine_resume_after_drop = coroutine resumed after async drop
middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking
middle_assert_coroutine_resume_after_return = coroutine resumed after completion
middle_assert_divide_by_zero =
attempt to divide `{$val}` by zero
middle_assert_gen_resume_after_drop = `gen` fn or block cannot be further iterated on after it async dropped
middle_assert_gen_resume_after_panic = `gen` fn or block cannot be further iterated on after it panicked
middle_assert_invalid_enum_construction =
trying to construct an enum from an invalid value `{$source}`
middle_assert_misaligned_ptr_deref =
misaligned pointer dereference: address must be a multiple of {$required} but is {$found}
middle_assert_null_ptr_deref =
null pointer dereference occurred
middle_assert_op_overflow =
attempt to compute `{$left} {$op} {$right}`, which would overflow
middle_assert_overflow_neg =
attempt to negate `{$val}`, which would overflow
middle_assert_remainder_by_zero =
attempt to calculate the remainder of `{$val}` with a divisor of zero
middle_assert_shl_overflow =
attempt to shift left by `{$val}`, which would overflow
middle_assert_shr_overflow =
attempt to shift right by `{$val}`, which would overflow
middle_autodiff_unsafe_inner_const_ref = reading from a `Duplicated` const {$ty} is unsafe
middle_bounds_check =
index out of bounds: the length is {$len} but the index is {$index}
middle_conflict_types =
this expression supplies two conflicting concrete types for the same opaque type
middle_consider_type_length_limit =
consider adding a `#![type_length_limit="{$type_length}"]` attribute to your crate
middle_const_eval_non_int =
constant evaluation of enum discriminant resulted in non-integer
middle_const_not_used_in_type_alias =
const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias
middle_deprecated = use of deprecated {$kind} `{$path}`{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_in_future = use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_in_version = use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_suggestion = replace the use of the deprecated {$kind}
middle_drop_check_overflow =
overflow while adding drop-check rules for `{$ty}`
.note = overflowed on `{$overflow_ty}`
middle_erroneous_constant = erroneous constant encountered
middle_failed_writing_file =
failed to write file {$path}: {$error}"
# Note: We only mention patterns here since the error can only occur with references, and those
# are forbidden in const generics.
middle_invalid_const_in_valtree = constant {$global_const_id} cannot be used as pattern
.note = constants that reference mutable or external memory cannot be used as patterns
middle_layout_cycle =
a cycle occurred during layout computation
middle_layout_normalization_failure =
unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized
middle_layout_references_error =
the type has an unknown layout
middle_layout_simd_too_many =
the SIMD type `{$ty}` has more elements than the limit {$max_lanes}
middle_layout_simd_zero_length =
the SIMD type `{$ty}` has zero elements
middle_layout_size_overflow =
values of the type `{$ty}` are too big for the target architecture
middle_layout_too_generic = the type `{$ty}` does not have a fixed layout
middle_layout_unknown =
the type `{$ty}` has an unknown layout
middle_max_num_nodes_in_valtree = maximum number of nodes exceeded in constant {$global_const_id}
middle_opaque_hidden_type_mismatch =
concrete type differs from previous defining opaque type use
.label = expected `{$self_ty}`, got `{$other_ty}`
middle_previous_use_here =
previous use here
middle_recursion_limit_reached =
reached the recursion limit finding the struct tail for `{$ty}`
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]`
middle_requires_lang_item = requires `{$name}` lang_item
middle_strict_coherence_needs_negative_coherence =
to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled
.label = due to this attribute
middle_type_length_limit = reached the type-length limit while instantiating `{$instance}`
middle_unsupported_union = we don't support unions yet: '{$ty_name}'

View file

@ -1,11 +1,7 @@
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
use rustc_hir::def_id::DefId;
use rustc_hir::definitions::DefPathHash;
use rustc_hir::{HirId, ItemLocalId, OwnerId};
pub use rustc_query_system::dep_graph::DepNode;
use rustc_query_system::dep_graph::FingerprintStyle;
pub use rustc_query_system::dep_graph::dep_node::DepKind;
pub(crate) use rustc_query_system::dep_graph::{DepContext, DepNodeParams};
use rustc_query_system::dep_graph::dep_node::DepKind;
use rustc_query_system::dep_graph::{DepContext, DepNode, FingerprintStyle};
use rustc_span::Symbol;
use crate::mir::mono::MonoItem;
@ -176,223 +172,3 @@ pub fn dep_kind_from_label(label: &str) -> DepKind {
dep_kind_from_label_string(label)
.unwrap_or_else(|_| panic!("Query label {label} does not exist"))
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for () {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::Unit
}
#[inline(always)]
fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
Fingerprint::ZERO
}
#[inline(always)]
fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
Some(())
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for DefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
tcx.def_path_hash(*self).0
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
tcx.def_path_str(*self)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx)
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalDefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx).map(|id| id.expect_local())
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for OwnerId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() })
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for CrateNum {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
let def_id = self.as_def_id();
def_id.to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
tcx.crate_name(*self).to_string()
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx).map(|id| id.krate)
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for (DefId, DefId) {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::Opaque
}
// We actually would not need to specialize the implementation of this
// method but it's faster to combine the hashes than to instantiate a full
// hashing context and stable-hashing state.
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
let (def_id_0, def_id_1) = *self;
let def_path_hash_0 = tcx.def_path_hash(def_id_0);
let def_path_hash_1 = tcx.def_path_hash(def_id_1);
def_path_hash_0.0.combine(def_path_hash_1.0)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
let (def_id_0, def_id_1) = *self;
format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1))
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::HirId
}
// We actually would not need to specialize the implementation of this
// method but it's faster to combine the hashes than to instantiate a full
// hashing context and stable-hashing state.
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
let HirId { owner, local_id } = *self;
let def_path_hash = tcx.def_path_hash(owner.to_def_id());
Fingerprint::new(
// `owner` is local, so is completely defined by the local hash
def_path_hash.local_hash(),
local_id.as_u32() as u64,
)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
let HirId { owner, local_id } = *self;
format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32())
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local();
let local_id = local_id
.as_u64()
.try_into()
.unwrap_or_else(|_| panic!("local id should be u32, found {local_id:?}"));
Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
} else {
None
}
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for ModDefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
}
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for LocalModDefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
}
}

View file

@ -0,0 +1,228 @@
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
use rustc_hir::definitions::DefPathHash;
use rustc_hir::{HirId, ItemLocalId, OwnerId};
use rustc_query_system::dep_graph::{DepContext, DepNode, DepNodeKey, FingerprintStyle};
use crate::dep_graph::DepNodeExt;
use crate::ty::TyCtxt;
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for () {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::Unit
}
#[inline(always)]
fn to_fingerprint(&self, _: TyCtxt<'tcx>) -> Fingerprint {
Fingerprint::ZERO
}
#[inline(always)]
fn recover(_: TyCtxt<'tcx>, _: &DepNode) -> Option<Self> {
Some(())
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for DefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
tcx.def_path_hash(*self).0
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
tcx.def_path_str(*self)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx)
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for LocalDefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx).map(|id| id.expect_local())
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for OwnerId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx).map(|id| OwnerId { def_id: id.expect_local() })
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for CrateNum {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
let def_id = self.as_def_id();
def_id.to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
tcx.crate_name(*self).to_string()
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
dep_node.extract_def_id(tcx).map(|id| id.krate)
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for (DefId, DefId) {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::Opaque
}
// We actually would not need to specialize the implementation of this
// method but it's faster to combine the hashes than to instantiate a full
// hashing context and stable-hashing state.
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
let (def_id_0, def_id_1) = *self;
let def_path_hash_0 = tcx.def_path_hash(def_id_0);
let def_path_hash_1 = tcx.def_path_hash(def_id_1);
def_path_hash_0.0.combine(def_path_hash_1.0)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
let (def_id_0, def_id_1) = *self;
format!("({}, {})", tcx.def_path_debug_str(def_id_0), tcx.def_path_debug_str(def_id_1))
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for HirId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::HirId
}
// We actually would not need to specialize the implementation of this
// method but it's faster to combine the hashes than to instantiate a full
// hashing context and stable-hashing state.
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
let HirId { owner, local_id } = *self;
let def_path_hash = tcx.def_path_hash(owner.to_def_id());
Fingerprint::new(
// `owner` is local, so is completely defined by the local hash
def_path_hash.local_hash(),
local_id.as_u32() as u64,
)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
let HirId { owner, local_id } = *self;
format!("{}.{}", tcx.def_path_str(owner), local_id.as_u32())
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
if tcx.fingerprint_style(dep_node.kind) == FingerprintStyle::HirId {
let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
let def_id = tcx.def_path_hash_to_def_id(def_path_hash)?.expect_local();
let local_id = local_id
.as_u64()
.try_into()
.unwrap_or_else(|_| panic!("local id should be u32, found {local_id:?}"));
Some(HirId { owner: OwnerId { def_id }, local_id: ItemLocalId::from_u32(local_id) })
} else {
None
}
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for ModDefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
}
}
impl<'tcx> DepNodeKey<TyCtxt<'tcx>> for LocalModDefId {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
#[inline(always)]
fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
self.to_def_id().to_fingerprint(tcx)
}
#[inline(always)]
fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
self.to_def_id().to_debug_str(tcx)
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
}
}

View file

@ -7,15 +7,17 @@ use crate::ty::{self, TyCtxt};
#[macro_use]
mod dep_node;
mod dep_node_key;
pub use dep_node::{DepKind, DepNode, DepNodeExt, dep_kind_from_label, dep_kinds, label_strs};
pub(crate) use dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata};
pub use rustc_query_system::dep_graph::debug::{DepNodeFilter, EdgeFilter};
pub use rustc_query_system::dep_graph::{
DepContext, DepGraphQuery, DepNodeIndex, Deps, SerializedDepGraph, SerializedDepNodeIndex,
TaskDepsRef, WorkProduct, WorkProductId, WorkProductMap, hash_result,
DepContext, DepGraphQuery, DepKind, DepNode, DepNodeIndex, Deps, SerializedDepGraph,
SerializedDepNodeIndex, TaskDepsRef, WorkProduct, WorkProductId, WorkProductMap, hash_result,
};
pub use self::dep_node::{DepNodeExt, dep_kind_from_label, dep_kinds, label_strs};
pub(crate) use self::dep_node::{make_compile_codegen_unit, make_compile_mono_item, make_metadata};
pub type DepGraph = rustc_query_system::dep_graph::DepGraph<DepsType>;
pub type DepKindVTable<'tcx> = rustc_query_system::dep_graph::DepKindVTable<TyCtxt<'tcx>>;

View file

@ -9,8 +9,8 @@ use rustc_span::{Span, Symbol};
use crate::ty::{Instance, Ty};
#[derive(Diagnostic)]
#[diag(middle_drop_check_overflow, code = E0320)]
#[note]
#[diag("overflow while adding drop-check rules for `{$ty}`", code = E0320)]
#[note("overflowed on `{$overflow_ty}`")]
pub(crate) struct DropCheckOverflow<'tcx> {
#[primary_span]
pub span: Span,
@ -19,33 +19,33 @@ pub(crate) struct DropCheckOverflow<'tcx> {
}
#[derive(Diagnostic)]
#[diag(middle_failed_writing_file)]
#[diag("failed to write file {$path}: {$error}\"")]
pub(crate) struct FailedWritingFile<'a> {
pub path: &'a Path,
pub error: io::Error,
}
#[derive(Diagnostic)]
#[diag(middle_opaque_hidden_type_mismatch)]
#[diag("concrete type differs from previous defining opaque type use")]
pub(crate) struct OpaqueHiddenTypeMismatch<'tcx> {
pub self_ty: Ty<'tcx>,
pub other_ty: Ty<'tcx>,
#[primary_span]
#[label]
#[label("expected `{$self_ty}`, got `{$other_ty}`")]
pub other_span: Span,
#[subdiagnostic]
pub sub: TypeMismatchReason,
}
#[derive(Diagnostic)]
#[diag(middle_unsupported_union)]
#[diag("we don't support unions yet: '{$ty_name}'")]
pub struct UnsupportedUnion {
pub ty_name: String,
}
// FIXME(autodiff): I should get used somewhere
#[derive(Diagnostic)]
#[diag(middle_autodiff_unsafe_inner_const_ref)]
#[diag("reading from a `Duplicated` const {$ty} is unsafe")]
pub struct AutodiffUnsafeInnerConstRef<'tcx> {
#[primary_span]
pub span: Span,
@ -54,12 +54,12 @@ pub struct AutodiffUnsafeInnerConstRef<'tcx> {
#[derive(Subdiagnostic)]
pub enum TypeMismatchReason {
#[label(middle_conflict_types)]
#[label("this expression supplies two conflicting concrete types for the same opaque type")]
ConflictType {
#[primary_span]
span: Span,
},
#[note(middle_previous_use_here)]
#[note("previous use here")]
PreviousUse {
#[primary_span]
span: Span,
@ -67,8 +67,10 @@ pub enum TypeMismatchReason {
}
#[derive(Diagnostic)]
#[diag(middle_recursion_limit_reached)]
#[help]
#[diag("reached the recursion limit finding the struct tail for `{$ty}`")]
#[help(
"consider increasing the recursion limit by adding a `#![recursion_limit = \"{$suggested_limit}\"]`"
)]
pub(crate) struct RecursionLimitReached<'tcx> {
#[primary_span]
pub span: Span,
@ -77,23 +79,25 @@ pub(crate) struct RecursionLimitReached<'tcx> {
}
#[derive(Diagnostic)]
#[diag(middle_const_eval_non_int)]
#[diag("constant evaluation of enum discriminant resulted in non-integer")]
pub(crate) struct ConstEvalNonIntError {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(middle_strict_coherence_needs_negative_coherence)]
#[diag(
"to use `strict_coherence` on this trait, the `with_negative_coherence` feature must be enabled"
)]
pub(crate) struct StrictCoherenceNeedsNegativeCoherence {
#[primary_span]
pub span: Span,
#[label]
#[label("due to this attribute")]
pub attr_span: Option<Span>,
}
#[derive(Diagnostic)]
#[diag(middle_requires_lang_item)]
#[diag("requires `{$name}` lang_item")]
pub(crate) struct RequiresLangItem {
#[primary_span]
pub span: Span,
@ -101,7 +105,9 @@ pub(crate) struct RequiresLangItem {
}
#[derive(Diagnostic)]
#[diag(middle_const_not_used_in_type_alias)]
#[diag(
"const parameter `{$ct}` is part of concrete type but not used in parameter list for the `impl Trait` type alias"
)]
pub(super) struct ConstNotUsedTraitAlias {
pub ct: String,
#[primary_span]
@ -133,41 +139,41 @@ impl fmt::Debug for CustomSubdiagnostic<'_> {
#[derive(Diagnostic)]
pub enum LayoutError<'tcx> {
#[diag(middle_layout_unknown)]
#[diag("the type `{$ty}` has an unknown layout")]
Unknown { ty: Ty<'tcx> },
#[diag(middle_layout_too_generic)]
#[diag("the type `{$ty}` does not have a fixed layout")]
TooGeneric { ty: Ty<'tcx> },
#[diag(middle_layout_size_overflow)]
#[diag("values of the type `{$ty}` are too big for the target architecture")]
Overflow { ty: Ty<'tcx> },
#[diag(middle_layout_simd_too_many)]
#[diag("the SIMD type `{$ty}` has more elements than the limit {$max_lanes}")]
SimdTooManyLanes { ty: Ty<'tcx>, max_lanes: u64 },
#[diag(middle_layout_simd_zero_length)]
#[diag("the SIMD type `{$ty}` has zero elements")]
SimdZeroLength { ty: Ty<'tcx> },
#[diag(middle_layout_normalization_failure)]
#[diag("unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized")]
NormalizationFailure { ty: Ty<'tcx>, failure_ty: String },
#[diag(middle_layout_cycle)]
#[diag("a cycle occurred during layout computation")]
Cycle,
#[diag(middle_layout_references_error)]
#[diag("the type has an unknown layout")]
ReferencesError,
}
#[derive(Diagnostic)]
#[diag(middle_erroneous_constant)]
#[diag("erroneous constant encountered")]
pub(crate) struct ErroneousConstant {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(middle_type_length_limit)]
#[help(middle_consider_type_length_limit)]
#[diag("reached the type-length limit while instantiating `{$instance}`")]
#[help("consider adding a `#![type_length_limit=\"{$type_length}\"]` attribute to your crate")]
pub(crate) struct TypeLengthLimit<'tcx> {
#[primary_span]
pub span: Span,
@ -176,7 +182,7 @@ pub(crate) struct TypeLengthLimit<'tcx> {
}
#[derive(Diagnostic)]
#[diag(middle_max_num_nodes_in_valtree)]
#[diag("maximum number of nodes exceeded in constant {$global_const_id}")]
pub(crate) struct MaxNumNodesInValtree {
#[primary_span]
pub span: Span,
@ -184,8 +190,8 @@ pub(crate) struct MaxNumNodesInValtree {
}
#[derive(Diagnostic)]
#[diag(middle_invalid_const_in_valtree)]
#[note]
#[diag("constant {$global_const_id} cannot be used as pattern")]
#[note("constants that reference mutable or external memory cannot be used as patterns")]
pub(crate) struct InvalidConstInValtree {
#[primary_span]
pub span: Span,

View file

@ -81,7 +81,6 @@ pub mod thir;
pub mod traits;
pub mod ty;
pub mod util;
mod values;
#[macro_use]
pub mod query;
@ -92,5 +91,3 @@ pub mod dep_graph;
// Allows macros to refer to this crate as `::rustc_middle`
extern crate self as rustc_middle;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -4,7 +4,7 @@
use std::num::NonZero;
use rustc_ast::NodeId;
use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer};
use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintBuffer, inline_fluent};
use rustc_feature::GateIssue;
use rustc_hir::attrs::{DeprecatedSince, Deprecation};
use rustc_hir::def_id::{DefId, LocalDefId};
@ -103,7 +103,7 @@ fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
#[derive(Subdiagnostic)]
#[suggestion(
middle_deprecated_suggestion,
"replace the use of the deprecated {$kind}",
code = "{suggestion}",
style = "verbose",
applicability = "machine-applicable"
@ -128,10 +128,19 @@ pub struct Deprecated {
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
diag.primary_message(match &self.since_kind {
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
DeprecatedSinceKind::InEffect => inline_fluent!("use of deprecated {$kind} `{$path}`{$has_note ->
[true] : {$note}
*[other] {\"\"}
}"),
DeprecatedSinceKind::InFuture => inline_fluent!("use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
[true] : {$note}
*[other] {\"\"}
}"),
DeprecatedSinceKind::InVersion(_) => {
crate::fluent_generated::middle_deprecated_in_version
inline_fluent!("use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
[true] : {$note}
*[other] {\"\"}
}")
}
});
diag.arg("kind", self.kind);

View file

@ -336,18 +336,26 @@ impl<O> AssertKind<O> {
pub fn diagnostic_message(&self) -> DiagMessage {
use AssertKind::*;
use crate::fluent_generated::*;
match self {
BoundsCheck { .. } => middle_bounds_check,
Overflow(BinOp::Shl, _, _) => middle_assert_shl_overflow,
Overflow(BinOp::Shr, _, _) => middle_assert_shr_overflow,
Overflow(_, _, _) => middle_assert_op_overflow,
OverflowNeg(_) => middle_assert_overflow_neg,
DivisionByZero(_) => middle_assert_divide_by_zero,
RemainderByZero(_) => middle_assert_remainder_by_zero,
BoundsCheck { .. } => inline_fluent!(
"index out of bounds: the length is {$len} but the index is {$index}"
),
Overflow(BinOp::Shl, _, _) => {
inline_fluent!("attempt to shift left by `{$val}`, which would overflow")
}
Overflow(BinOp::Shr, _, _) => {
inline_fluent!("attempt to shift right by `{$val}`, which would overflow")
}
Overflow(_, _, _) => {
inline_fluent!("attempt to compute `{$left} {$op} {$right}`, which would overflow")
}
OverflowNeg(_) => inline_fluent!("attempt to negate `{$val}`, which would overflow"),
DivisionByZero(_) => inline_fluent!("attempt to divide `{$val}` by zero"),
RemainderByZero(_) => inline_fluent!(
"attempt to calculate the remainder of `{$val}` with a divisor of zero"
),
ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
middle_assert_async_resume_after_return
inline_fluent!("`async fn` resumed after completion")
}
ResumedAfterReturn(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
todo!()
@ -356,36 +364,42 @@ impl<O> AssertKind<O> {
bug!("gen blocks can be resumed after they return and will keep returning `None`")
}
ResumedAfterReturn(CoroutineKind::Coroutine(_)) => {
middle_assert_coroutine_resume_after_return
inline_fluent!("coroutine resumed after completion")
}
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
middle_assert_async_resume_after_panic
inline_fluent!("`async fn` resumed after panicking")
}
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
todo!()
}
ResumedAfterPanic(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
middle_assert_gen_resume_after_panic
inline_fluent!("`gen` fn or block cannot be further iterated on after it panicked")
}
ResumedAfterPanic(CoroutineKind::Coroutine(_)) => {
middle_assert_coroutine_resume_after_panic
inline_fluent!("coroutine resumed after panicking")
}
NullPointerDereference => inline_fluent!("null pointer dereference occurred"),
InvalidEnumConstruction(_) => {
inline_fluent!("trying to construct an enum from an invalid value `{$source}`")
}
NullPointerDereference => middle_assert_null_ptr_deref,
InvalidEnumConstruction(_) => middle_assert_invalid_enum_construction,
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Async, _)) => {
middle_assert_async_resume_after_drop
inline_fluent!("`async fn` resumed after async drop")
}
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _)) => {
todo!()
}
ResumedAfterDrop(CoroutineKind::Desugared(CoroutineDesugaring::Gen, _)) => {
middle_assert_gen_resume_after_drop
inline_fluent!(
"`gen` fn or block cannot be further iterated on after it async dropped"
)
}
ResumedAfterDrop(CoroutineKind::Coroutine(_)) => {
middle_assert_coroutine_resume_after_drop
inline_fluent!("coroutine resumed after async drop")
}
MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref,
MisalignedPointerDereference { .. } => inline_fluent!(
"misaligned pointer dereference: address must be a multiple of {$required} but is {$found}"
),
}
}
@ -498,6 +512,7 @@ impl<'tcx> TerminatorKind<'tcx> {
}
pub use helper::*;
use rustc_errors::inline_fluent;
mod helper {
use super::*;

View file

@ -1588,11 +1588,6 @@ rustc_queries! {
separate_provide_extern
}
query is_ctfe_mir_available(key: DefId) -> bool {
desc { |tcx| "checking if item has CTFE MIR available: `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }
separate_provide_extern
}
query is_mir_available(key: DefId) -> bool {
desc { |tcx| "checking if item has MIR available: `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() }

View file

@ -1,7 +1,7 @@
//! Helper functions that serve as the immediate implementation of
//! `tcx.$query(..)` and its variations.
use rustc_query_system::dep_graph::{DepKind, DepNodeParams};
use rustc_query_system::dep_graph::{DepKind, DepNodeKey};
use rustc_query_system::query::{QueryCache, QueryMode, try_get_cached};
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
@ -86,7 +86,7 @@ pub(crate) fn query_feed<'tcx, Cache>(
value: Cache::Value,
) where
Cache: QueryCache,
Cache::Key: DepNodeParams<TyCtxt<'tcx>>,
Cache::Key: DepNodeKey<TyCtxt<'tcx>>,
{
let format_value = query_vtable.format_value;

View file

@ -13,6 +13,7 @@ mod keys;
pub mod on_disk_cache;
#[macro_use]
pub mod plumbing;
pub mod values;
pub fn describe_as_module(def_id: impl Into<LocalDefId>, tcx: TyCtxt<'_>) -> String {
let def_id = def_id.into();

View file

@ -32,7 +32,8 @@ pub type IsLoadableFromDiskFn<'tcx, Key> =
/// Stores function pointers and other metadata for a particular query.
///
/// Used indirectly by query plumbing in `rustc_query_system`, via a trait.
/// Used indirectly by query plumbing in `rustc_query_system` via a trait,
/// and also used directly by query plumbing in `rustc_query_impl`.
pub struct QueryVTable<'tcx, C: QueryCache> {
pub name: &'static str,
pub eval_always: bool,
@ -52,6 +53,12 @@ pub struct QueryVTable<'tcx, C: QueryCache> {
pub value_from_cycle_error:
fn(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed) -> C::Value,
pub format_value: fn(&C::Value) -> String,
/// Formats a human-readable description of this query and its key, as
/// specified by the `desc` query modifier.
///
/// Used when reporting query cycle errors and similar problems.
pub description_fn: fn(TyCtxt<'tcx>, C::Key) -> String,
}
pub struct QuerySystemFns {

View file

@ -7,7 +7,6 @@ use rustc_errors::codes::*;
use rustc_errors::{Applicability, MultiSpan, pluralize, struct_span_code_err};
use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res};
use rustc_query_system::Value;
use rustc_query_system::query::{CycleError, report_cycle};
use rustc_span::def_id::LocalDefId;
use rustc_span::{ErrorGuaranteed, Span};
@ -16,7 +15,27 @@ use crate::dep_graph::dep_kinds;
use crate::query::plumbing::CyclePlaceholder;
use crate::ty::{self, Representability, Ty, TyCtxt};
impl<'tcx> Value<TyCtxt<'tcx>> for Ty<'_> {
pub trait Value<'tcx>: Sized {
fn from_cycle_error(tcx: TyCtxt<'tcx>, cycle_error: &CycleError, guar: ErrorGuaranteed)
-> Self;
}
impl<'tcx, T> Value<'tcx> for T {
default fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
_guar: ErrorGuaranteed,
) -> T {
tcx.sess.dcx().abort_if_errors();
bug!(
"<{} as Value>::from_cycle_error called without errors: {:#?}",
std::any::type_name::<T>(),
cycle_error.cycle,
);
}
}
impl<'tcx> Value<'tcx> for Ty<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self {
// SAFETY: This is never called when `Self` is not `Ty<'tcx>`.
// FIXME: Represent the above fact in the trait system somehow.
@ -24,13 +43,13 @@ impl<'tcx> Value<TyCtxt<'tcx>> for Ty<'_> {
}
}
impl<'tcx> Value<TyCtxt<'tcx>> for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
impl<'tcx> Value<'tcx> for Result<ty::EarlyBinder<'_, Ty<'_>>, CyclePlaceholder> {
fn from_cycle_error(_tcx: TyCtxt<'tcx>, _: &CycleError, guar: ErrorGuaranteed) -> Self {
Err(CyclePlaceholder(guar))
}
}
impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
impl<'tcx> Value<'tcx> for ty::SymbolName<'_> {
fn from_cycle_error(tcx: TyCtxt<'tcx>, _: &CycleError, _guar: ErrorGuaranteed) -> Self {
// SAFETY: This is never called when `Self` is not `SymbolName<'tcx>`.
// FIXME: Represent the above fact in the trait system somehow.
@ -42,7 +61,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::SymbolName<'_> {
}
}
impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
impl<'tcx> Value<'tcx> for ty::Binder<'_, ty::FnSig<'_>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
@ -76,7 +95,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
}
}
impl<'tcx> Value<TyCtxt<'tcx>> for Representability {
impl<'tcx> Value<'tcx> for Representability {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
@ -112,7 +131,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for Representability {
}
}
impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<'_, Ty<'_>> {
impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, Ty<'_>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
@ -122,7 +141,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<'_, Ty<'_>> {
}
}
impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> {
impl<'tcx> Value<'tcx> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<'_>>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
@ -132,7 +151,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::EarlyBinder<'_, ty::Binder<'_, ty::FnSig<
}
}
impl<'tcx> Value<TyCtxt<'tcx>> for &[ty::Variance] {
impl<'tcx> Value<'tcx> for &[ty::Variance] {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
@ -180,7 +199,7 @@ fn search_for_cycle_permutation<Q, T>(
otherwise()
}
impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>> {
impl<'tcx, T> Value<'tcx> for Result<T, &'_ ty::layout::LayoutError<'_>> {
fn from_cycle_error(
tcx: TyCtxt<'tcx>,
cycle_error: &CycleError,
@ -273,7 +292,7 @@ impl<'tcx, T> Value<TyCtxt<'tcx>> for Result<T, &'_ ty::layout::LayoutError<'_>>
// item_and_field_ids should form a cycle where each field contains the
// type in the next element in the list
pub fn recursive_type_error(
fn recursive_type_error(
tcx: TyCtxt<'_>,
mut item_and_field_ids: Vec<(LocalDefId, LocalDefId)>,
representable_ids: &FxHashSet<LocalDefId>,

View file

@ -526,12 +526,15 @@ pub fn suggest_constraining_type_params<'a>(
//
// fn foo<T>(t: T) { ... }
// - help: consider restricting this type parameter with `T: Foo`
suggestions.push((
param.span.shrink_to_hi(),
post,
format!(": {constraint}"),
SuggestChangingConstraintsMessage::RestrictType { ty: param_name },
));
let span = param.span.shrink_to_hi();
if span.can_be_used_for_suggestions() {
suggestions.push((
span,
post,
format!(": {constraint}"),
SuggestChangingConstraintsMessage::RestrictType { ty: param_name },
));
}
}
// FIXME: remove the suggestions that are from derive, as the span is not correct

View file

@ -9,6 +9,7 @@ use rustc_abi::{
use rustc_error_messages::DiagMessage;
use rustc_errors::{
Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, IntoDiagArg, Level,
inline_fluent,
};
use rustc_hir::LangItem;
use rustc_hir::def_id::DefId;
@ -268,18 +269,25 @@ impl<'tcx> LayoutError<'tcx> {
pub fn diagnostic_message(&self) -> DiagMessage {
use LayoutError::*;
use crate::fluent_generated::*;
match self {
Unknown(_) => middle_layout_unknown,
SizeOverflow(_) => middle_layout_size_overflow,
InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => {
middle_layout_simd_too_many
Unknown(_) => inline_fluent!("the type `{$ty}` has an unknown layout"),
SizeOverflow(_) => {
inline_fluent!("values of the type `{$ty}` are too big for the target architecture")
}
InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => middle_layout_simd_zero_length,
TooGeneric(_) => middle_layout_too_generic,
NormalizationFailure(_, _) => middle_layout_normalization_failure,
Cycle(_) => middle_layout_cycle,
ReferencesError(_) => middle_layout_references_error,
InvalidSimd { kind: SimdLayoutError::TooManyLanes(_), .. } => {
inline_fluent!(
"the SIMD type `{$ty}` has more elements than the limit {$max_lanes}"
)
}
InvalidSimd { kind: SimdLayoutError::ZeroLength, .. } => {
inline_fluent!("the SIMD type `{$ty}` has zero elements")
}
TooGeneric(_) => inline_fluent!("the type `{$ty}` does not have a fixed layout"),
NormalizationFailure(_, _) => inline_fluent!(
"unable to determine layout for `{$ty}` because `{$failure_ty}` cannot be normalized"
),
Cycle(_) => inline_fluent!("a cycle occurred during layout computation"),
ReferencesError(_) => inline_fluent!("the type has an unknown layout"),
}
}

View file

@ -13,7 +13,6 @@ rustc_ast = { path = "../rustc_ast" }
rustc_const_eval = { path = "../rustc_const_eval" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }
rustc_infer = { path = "../rustc_infer" }

View file

@ -1,114 +0,0 @@
mir_transform_arithmetic_overflow = this arithmetic operation will overflow
mir_transform_asm_unwind_call = call to inline assembly that may unwind
mir_transform_const_defined_here = `const` item defined here
mir_transform_const_modify = attempting to modify a `const` item
.note = each usage of a `const` item creates a new temporary; the original `const` item will not be modified
mir_transform_const_mut_borrow = taking a mutable reference to a `const` item
.note = each usage of a `const` item creates a new temporary
.note2 = the mutable reference will refer to this temporary, not the original `const` item
.note3 = mutable reference created due to call to this method
mir_transform_ffi_unwind_call = call to {$foreign ->
[true] foreign function
*[false] function pointer
} with FFI-unwind ABI
mir_transform_fn_item_ref = taking a reference to a function item does not give a function pointer
.suggestion = cast `{$ident}` to obtain a function pointer
mir_transform_force_inline =
`{$callee}` could not be inlined into `{$caller}` but is required to be inlined
.call = ...`{$callee}` called here
.attr = inlining due to this annotation
.caller = within `{$caller}`...
.callee = `{$callee}` defined here
.note = could not be inlined due to: {$reason}
mir_transform_force_inline_attr =
`{$callee}` is incompatible with `#[rustc_force_inline]`
.attr = annotation here
.callee = `{$callee}` defined here
.note = incompatible due to: {$reason}
mir_transform_force_inline_justification =
`{$callee}` is required to be inlined to: {$sym}
mir_transform_maybe_string_interpolation = you might have meant to use string interpolation in this string literal
mir_transform_must_not_suspend = {$pre}`{$def_path}`{$post} held across a suspend point, but should not be
.label = the value is held across this suspend point
.note = {$reason}
.help = consider using a block (`{"{ ... }"}`) to shrink the value's scope, ending before the suspend point
mir_transform_operation_will_panic = this operation will panic at runtime
mir_transform_string_interpolation_only_works = string interpolation only works in `format!` invocations
mir_transform_tail_expr_drop_order = relative drop order changing in Rust 2024
.temporaries = in Rust 2024, this temporary value will be dropped first
.observers = in Rust 2024, this local variable or temporary value will be dropped second
.note_dtors =
dropping the temporary value runs this custom `Drop` impl, which we could not prove to be side-effect free
.note_observer_dtors =
dropping the local runs this custom `Drop` impl, which we could not prove to be side-effect free
.drop_location =
now the temporary value is dropped here, before the local variables in the block or statement
.note_epilogue = most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages
.label_local_epilogue = {$is_dropped_first_edition_2024 ->
[true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024
*[false] `{$name}` will be dropped later as of Edition 2024
}
mir_transform_tail_expr_dtor = {$dtor_kind ->
[dyn] `{$name}` may invoke a custom destructor because it contains a trait object
*[concrete] `{$name}` invokes this custom destructor
}
mir_transform_tail_expr_local = {$is_generated_name ->
[true] this value will be stored in a temporary; let us call it `{$name}`
*[false] `{$name}` calls a custom destructor
}
mir_transform_unaligned_packed_ref = reference to field of packed {$ty_descr} is unaligned
.note = this {$ty_descr} is {$align ->
[one] {""}
*[other] {"at most "}
}{$align}-byte aligned, but the type of this field may require higher alignment
.note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
.help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
mir_transform_unconditional_recursion = function cannot return without recursing
.label = cannot return without recursing
.help = a `loop` may express intention better if this is on purpose
mir_transform_unconditional_recursion_call_site_label = recursive call site
mir_transform_unknown_pass_name = MIR pass `{$name}` is unknown and will be ignored
mir_transform_unused_assign = value assigned to `{$name}` is never read
.help = maybe it is overwritten before being read?
mir_transform_unused_assign_passed = value passed to `{$name}` is never read
.help = maybe it is overwritten before being read?
mir_transform_unused_assign_suggestion =
you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding
mir_transform_unused_capture_maybe_capture_ref = value captured by `{$name}` is never read
.help = did you mean to capture by reference instead?
mir_transform_unused_var_assigned_only = variable `{$name}` is assigned to, but never used
.note = consider using `_{$name}` instead
mir_transform_unused_var_underscore = if this is intentional, prefix it with an underscore
mir_transform_unused_variable = unused variable: `{$name}`
mir_transform_unused_variable_args_in_macro = `{$name}` is captured in macro and introduced a unused variable
mir_transform_unused_variable_try_ignore = try ignoring the field
mir_transform_unused_variable_typo = you might have meant to pattern match on the similarly named {$kind} `{$item_name}`

View file

@ -1,5 +1,7 @@
use rustc_errors::codes::*;
use rustc_errors::{Applicability, Diag, EmissionGuarantee, LintDiagnostic, Subdiagnostic};
use rustc_errors::{
Applicability, Diag, EmissionGuarantee, LintDiagnostic, Subdiagnostic, inline_fluent,
};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::mir::AssertKind;
use rustc_middle::query::Key;
@ -8,8 +10,6 @@ use rustc_session::lint::{self, Lint};
use rustc_span::def_id::DefId;
use rustc_span::{Ident, Span, Symbol};
use crate::fluent_generated as fluent;
/// Emit diagnostic for calls to `#[inline(always)]`-annotated functions with a
/// `#[target_feature]` attribute where the caller enables a different set of target features.
pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>(
@ -51,22 +51,22 @@ pub(crate) fn emit_inline_always_target_feature_diagnostic<'a, 'tcx>(
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_unconditional_recursion)]
#[help]
#[diag("function cannot return without recursing")]
#[help("a `loop` may express intention better if this is on purpose")]
pub(crate) struct UnconditionalRecursion {
#[label]
#[label("cannot return without recursing")]
pub(crate) span: Span,
#[label(mir_transform_unconditional_recursion_call_site_label)]
#[label("recursive call site")]
pub(crate) call_sites: Vec<Span>,
}
#[derive(Diagnostic)]
#[diag(mir_transform_force_inline_attr)]
#[note]
#[diag("`{$callee}` is incompatible with `#[rustc_force_inline]`")]
#[note("incompatible due to: {$reason}")]
pub(crate) struct InvalidForceInline {
#[primary_span]
pub attr_span: Span,
#[label(mir_transform_callee)]
#[label("`{$callee}` defined here")]
pub callee_span: Span,
pub callee: String,
pub reason: &'static str,
@ -74,28 +74,39 @@ pub(crate) struct InvalidForceInline {
#[derive(LintDiagnostic)]
pub(crate) enum ConstMutate {
#[diag(mir_transform_const_modify)]
#[note]
#[diag("attempting to modify a `const` item")]
#[note(
"each usage of a `const` item creates a new temporary; the original `const` item will not be modified"
)]
Modify {
#[note(mir_transform_const_defined_here)]
#[note("`const` item defined here")]
konst: Span,
},
#[diag(mir_transform_const_mut_borrow)]
#[note]
#[note(mir_transform_note2)]
#[diag("taking a mutable reference to a `const` item")]
#[note("each usage of a `const` item creates a new temporary")]
#[note("the mutable reference will refer to this temporary, not the original `const` item")]
MutBorrow {
#[note(mir_transform_note3)]
#[note("mutable reference created due to call to this method")]
method_call: Option<Span>,
#[note(mir_transform_const_defined_here)]
#[note("`const` item defined here")]
konst: Span,
},
}
#[derive(Diagnostic)]
#[diag(mir_transform_unaligned_packed_ref, code = E0793)]
#[note]
#[note(mir_transform_note_ub)]
#[help]
#[diag("reference to field of packed {$ty_descr} is unaligned", code = E0793)]
#[note(
"this {$ty_descr} is {$align ->
[one] {\"\"}
*[other] {\"at most \"}
}{$align}-byte aligned, but the type of this field may require higher alignment"
)]
#[note(
"creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)"
)]
#[help(
"copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)"
)]
pub(crate) struct UnalignedPackedRef {
#[primary_span]
pub span: Span,
@ -104,7 +115,7 @@ pub(crate) struct UnalignedPackedRef {
}
#[derive(Diagnostic)]
#[diag(mir_transform_unknown_pass_name)]
#[diag("MIR pass `{$name}` is unknown and will be ignored")]
pub(crate) struct UnknownPassName<'a> {
pub(crate) name: &'a str,
}
@ -123,8 +134,12 @@ pub(crate) enum AssertLintKind {
impl<'a, P: std::fmt::Debug> LintDiagnostic<'a, ()> for AssertLint<P> {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(match self.lint_kind {
AssertLintKind::ArithmeticOverflow => fluent::mir_transform_arithmetic_overflow,
AssertLintKind::UnconditionalPanic => fluent::mir_transform_operation_will_panic,
AssertLintKind::ArithmeticOverflow => {
inline_fluent!("this arithmetic operation will overflow")
}
AssertLintKind::UnconditionalPanic => {
inline_fluent!("this operation will panic at runtime")
}
});
let label = self.assert_kind.diagnostic_message();
self.assert_kind.add_args(&mut |name, value| {
@ -144,39 +159,53 @@ impl AssertLintKind {
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_asm_unwind_call)]
#[diag("call to inline assembly that may unwind")]
pub(crate) struct AsmUnwindCall {
#[label(mir_transform_asm_unwind_call)]
#[label("call to inline assembly that may unwind")]
pub span: Span,
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_ffi_unwind_call)]
#[diag(
"call to {$foreign ->
[true] foreign function
*[false] function pointer
} with FFI-unwind ABI"
)]
pub(crate) struct FfiUnwindCall {
#[label(mir_transform_ffi_unwind_call)]
#[label(
"call to {$foreign ->
[true] foreign function
*[false] function pointer
} with FFI-unwind ABI"
)]
pub span: Span,
pub foreign: bool,
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_fn_item_ref)]
#[diag("taking a reference to a function item does not give a function pointer")]
pub(crate) struct FnItemRef {
#[suggestion(code = "{sugg}", applicability = "unspecified")]
#[suggestion(
"cast `{$ident}` to obtain a function pointer",
code = "{sugg}",
applicability = "unspecified"
)]
pub span: Span,
pub sugg: String,
pub ident: Ident,
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_unused_capture_maybe_capture_ref)]
#[help]
#[diag("value captured by `{$name}` is never read")]
#[help("did you mean to capture by reference instead?")]
pub(crate) struct UnusedCaptureMaybeCaptureRef {
pub name: Symbol,
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_unused_var_assigned_only)]
#[note]
#[diag("variable `{$name}` is assigned to, but never used")]
#[note("consider using `_{$name}` instead")]
pub(crate) struct UnusedVarAssignedOnly {
pub name: Symbol,
#[subdiagnostic]
@ -184,17 +213,20 @@ pub(crate) struct UnusedVarAssignedOnly {
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_unused_assign)]
#[diag("value assigned to `{$name}` is never read")]
pub(crate) struct UnusedAssign {
pub name: Symbol,
#[subdiagnostic]
pub suggestion: Option<UnusedAssignSuggestion>,
#[help]
#[help("maybe it is overwritten before being read?")]
pub help: bool,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(mir_transform_unused_assign_suggestion, applicability = "maybe-incorrect")]
#[multipart_suggestion(
"you might have meant to mutate the pointed at value being passed in, instead of changing the reference in the local binding",
applicability = "maybe-incorrect"
)]
pub(crate) struct UnusedAssignSuggestion {
pub pre: &'static str,
#[suggestion_part(code = "{pre}mut ")]
@ -208,14 +240,14 @@ pub(crate) struct UnusedAssignSuggestion {
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_unused_assign_passed)]
#[help]
#[diag("value passed to `{$name}` is never read")]
#[help("maybe it is overwritten before being read?")]
pub(crate) struct UnusedAssignPassed {
pub name: Symbol,
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_unused_variable)]
#[diag("unused variable: `{$name}`")]
pub(crate) struct UnusedVariable {
pub name: Symbol,
#[subdiagnostic]
@ -226,10 +258,7 @@ pub(crate) struct UnusedVariable {
#[derive(Subdiagnostic)]
pub(crate) enum UnusedVariableSugg {
#[multipart_suggestion(
mir_transform_unused_variable_try_ignore,
applicability = "machine-applicable"
)]
#[multipart_suggestion("try ignoring the field", applicability = "machine-applicable")]
TryIgnore {
#[suggestion_part(code = "{name}: _")]
shorthands: Vec<Span>,
@ -239,7 +268,7 @@ pub(crate) enum UnusedVariableSugg {
},
#[multipart_suggestion(
mir_transform_unused_var_underscore,
"if this is intentional, prefix it with an underscore",
applicability = "machine-applicable"
)]
TryPrefix {
@ -250,7 +279,7 @@ pub(crate) enum UnusedVariableSugg {
typo: Option<PatternTypo>,
},
#[help(mir_transform_unused_variable_args_in_macro)]
#[help("`{$name}` is captured in macro and introduced a unused variable")]
NoSugg {
#[primary_span]
span: Span,
@ -266,10 +295,12 @@ impl Subdiagnostic for UnusedVariableStringInterp {
fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
diag.span_label(
self.lit,
crate::fluent_generated::mir_transform_maybe_string_interpolation,
inline_fluent!(
"you might have meant to use string interpolation in this string literal"
),
);
diag.multipart_suggestion(
crate::fluent_generated::mir_transform_string_interpolation_only_works,
inline_fluent!("string interpolation only works in `format!` invocations"),
vec![
(self.lit.shrink_to_lo(), String::from("format!(")),
(self.lit.shrink_to_hi(), String::from(")")),
@ -281,7 +312,7 @@ impl Subdiagnostic for UnusedVariableStringInterp {
#[derive(Subdiagnostic)]
#[multipart_suggestion(
mir_transform_unused_variable_typo,
"you might have meant to pattern match on the similarly named {$kind} `{$item_name}`",
style = "verbose",
applicability = "maybe-incorrect"
)]
@ -306,12 +337,17 @@ pub(crate) struct MustNotSupend<'a, 'tcx> {
// Needed for def_path_str
impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> {
fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) {
diag.primary_message(fluent::mir_transform_must_not_suspend);
diag.span_label(self.yield_sp, fluent::_subdiag::label);
diag.primary_message(inline_fluent!(
"{$pre}`{$def_path}`{$post} held across a suspend point, but should not be"
));
diag.span_label(
self.yield_sp,
inline_fluent!("the value is held across this suspend point"),
);
if let Some(reason) = self.reason {
diag.subdiagnostic(reason);
}
diag.span_help(self.src_sp, fluent::_subdiag::help);
diag.span_help(self.src_sp, inline_fluent!("consider using a block (`{\"{ ... }\"}`) to shrink the value's scope, ending before the suspend point"));
diag.arg("pre", self.pre);
diag.arg("def_path", self.tcx.def_path_str(self.def_id));
diag.arg("post", self.post);
@ -319,7 +355,7 @@ impl<'a> LintDiagnostic<'a, ()> for MustNotSupend<'_, '_> {
}
#[derive(Subdiagnostic)]
#[note(mir_transform_note)]
#[note("{$reason}")]
pub(crate) struct MustNotSuspendReason {
#[primary_span]
pub span: Span,
@ -327,17 +363,17 @@ pub(crate) struct MustNotSuspendReason {
}
#[derive(Diagnostic)]
#[diag(mir_transform_force_inline)]
#[note]
#[diag("`{$callee}` could not be inlined into `{$caller}` but is required to be inlined")]
#[note("could not be inlined due to: {$reason}")]
pub(crate) struct ForceInlineFailure {
#[label(mir_transform_caller)]
#[label("within `{$caller}`...")]
pub caller_span: Span,
#[label(mir_transform_callee)]
#[label("`{$callee}` defined here")]
pub callee_span: Span,
#[label(mir_transform_attr)]
#[label("annotation here")]
pub attr_span: Span,
#[primary_span]
#[label(mir_transform_call)]
#[label("...`{$callee}` called here")]
pub call_span: Span,
pub callee: String,
pub caller: String,
@ -347,7 +383,7 @@ pub(crate) struct ForceInlineFailure {
}
#[derive(Subdiagnostic)]
#[note(mir_transform_force_inline_justification)]
#[note("`{$callee}` is required to be inlined to: {$sym}")]
pub(crate) struct ForceInlineJustification {
pub sym: Symbol,
}

View file

@ -213,8 +213,6 @@ declare_passes! {
mod validate : Validator;
}
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
pub fn provide(providers: &mut Providers) {
coverage::query::provide(providers);
ffi_unwind_calls::provide(&mut providers.queries);
@ -231,7 +229,6 @@ pub fn provide(providers: &mut Providers) {
optimized_mir,
check_liveness: liveness::check_liveness,
is_mir_available,
is_ctfe_mir_available: is_mir_available,
mir_callgraph_cyclic: inline::cycle::mir_callgraph_cyclic,
mir_inliner_callees: inline::cycle::mir_inliner_callees,
promoted_mir,

View file

@ -5,7 +5,7 @@ use std::rc::Rc;
use itertools::Itertools as _;
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::Subdiagnostic;
use rustc_errors::{Subdiagnostic, inline_fluent};
use rustc_hir::CRATE_HIR_ID;
use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::MixedBitSet;
@ -499,13 +499,17 @@ fn assign_observables_names(
}
#[derive(LintDiagnostic)]
#[diag(mir_transform_tail_expr_drop_order)]
#[diag("relative drop order changing in Rust 2024")]
struct TailExprDropOrderLint<'a> {
#[subdiagnostic]
local_labels: Vec<LocalLabel<'a>>,
#[label(mir_transform_drop_location)]
#[label(
"now the temporary value is dropped here, before the local variables in the block or statement"
)]
drop_span: Option<Span>,
#[note(mir_transform_note_epilogue)]
#[note(
"most of the time, changing drop order is harmless; inspect the `impl Drop`s for side effects like releasing locks or sending messages"
)]
_epilogue: (),
}
@ -527,19 +531,32 @@ impl Subdiagnostic for LocalLabel<'_> {
diag.arg("is_generated_name", self.is_generated_name);
diag.remove_arg("is_dropped_first_edition_2024");
diag.arg("is_dropped_first_edition_2024", self.is_dropped_first_edition_2024);
let msg = diag.eagerly_translate(crate::fluent_generated::mir_transform_tail_expr_local);
let msg = diag.eagerly_translate(inline_fluent!(
"{$is_generated_name ->
[true] this value will be stored in a temporary; let us call it `{$name}`
*[false] `{$name}` calls a custom destructor
}"
));
diag.span_label(self.span, msg);
for dtor in self.destructors {
dtor.add_to_diag(diag);
}
let msg =
diag.eagerly_translate(crate::fluent_generated::mir_transform_label_local_epilogue);
diag.eagerly_translate(inline_fluent!("{$is_dropped_first_edition_2024 ->
[true] up until Edition 2021 `{$name}` is dropped last but will be dropped earlier in Edition 2024
*[false] `{$name}` will be dropped later as of Edition 2024
}"));
diag.span_label(self.span, msg);
}
}
#[derive(Subdiagnostic)]
#[note(mir_transform_tail_expr_dtor)]
#[note(
"{$dtor_kind ->
[dyn] `{$name}` may invoke a custom destructor because it contains a trait object
*[concrete] `{$name}` invokes this custom destructor
}"
)]
struct DestructorLabel<'a> {
#[primary_span]
span: Span,

View file

@ -1085,7 +1085,9 @@ fn should_codegen_locally<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) ->
return false;
}
if !tcx.is_mir_available(def_id) {
// See comment in should_encode_mir in rustc_metadata for why we don't report
// an error for constructors.
if !tcx.is_mir_available(def_id) && !matches!(tcx.def_kind(def_id), DefKind::Ctor(..)) {
tcx.dcx().emit_fatal(NoOptimizedMir {
span: tcx.def_span(def_id),
crate_name: tcx.crate_name(def_id.krate),

View file

@ -441,8 +441,6 @@ passes_rustc_allow_const_fn_unstable =
passes_rustc_const_stable_indirect_pairing =
`const_stable_indirect` attribute does not make sense on `rustc_const_stable` function, its behavior is already implied
passes_rustc_dirty_clean =
attribute requires -Z query-dep-graph to be enabled
passes_rustc_force_inline_coro =
attribute cannot be applied to a `async`, `gen` or `async gen` function

Some files were not shown because too many files have changed in this diff Show more