diff --git a/Cargo.lock b/Cargo.lock index 430a1d149a2b5..9ea22911d5157 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3789,7 +3789,6 @@ dependencies = [ "rustc_mir_build", "rustc_mir_transform", "rustc_parse", - "rustc_passes", "rustc_public", "rustc_resolve", "rustc_session", @@ -4417,7 +4416,6 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_feature", - "rustc_fluent_macro", "rustc_hir", "rustc_index", "rustc_macros", diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e4f431fd2431c..e4698ce8d6db4 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -2570,7 +2570,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ConstArg { hir_id: self.lower_node_id(expr.id), - kind: hir::ConstArgKind::Literal(literal.node), + kind: hir::ConstArgKind::Literal { lit: literal.node, negated: false }, + span, + } + } + ExprKind::Unary(UnOp::Neg, inner_expr) + if let ExprKind::Lit(literal) = &inner_expr.kind => + { + let span = expr.span; + let literal = self.lower_lit(literal, span); + + ConstArg { + hir_id: self.lower_node_id(expr.id), + kind: hir::ConstArgKind::Literal { lit: literal.node, negated: true }, span, } } diff --git a/compiler/rustc_driver_impl/Cargo.toml b/compiler/rustc_driver_impl/Cargo.toml index d28a190ea9c18..10e1b1987194a 100644 --- a/compiler/rustc_driver_impl/Cargo.toml +++ b/compiler/rustc_driver_impl/Cargo.toml @@ -29,7 +29,6 @@ rustc_middle = { path = "../rustc_middle" } 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_public = { path = "../rustc_public", features = ["rustc_internal"] } rustc_resolve = { path = "../rustc_resolve" } rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs index 72831a8d8ff6f..4bbcf7373589c 100644 --- a/compiler/rustc_driver_impl/src/lib.rs +++ b/compiler/rustc_driver_impl/src/lib.rs @@ -117,7 +117,6 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[ rustc_lint::DEFAULT_LOCALE_RESOURCE, rustc_mir_build::DEFAULT_LOCALE_RESOURCE, rustc_parse::DEFAULT_LOCALE_RESOURCE, - rustc_passes::DEFAULT_LOCALE_RESOURCE, // tidy-alphabetical-end ]; diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index b117fa8327296..cf96f33e98918 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -521,7 +521,10 @@ pub enum ConstArgKind<'hir, Unambig = ()> { /// This variant is not always used to represent inference consts, sometimes /// [`GenericArg::Infer`] is used instead. Infer(Unambig), - Literal(LitKind), + Literal { + lit: LitKind, + negated: bool, + }, } #[derive(Clone, Copy, Debug, HashStable_Generic)] @@ -1958,8 +1961,6 @@ pub struct PatExpr<'hir> { pub enum PatExprKind<'hir> { Lit { lit: Lit, - // FIXME: move this into `Lit` and handle negated literal expressions - // once instead of matching on unop neg expressions everywhere. negated: bool, }, /// A path pattern for a unit struct/variant or a (maybe-associated) constant. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index d1b75325af268..bd863abaceb4c 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -1110,7 +1110,7 @@ pub fn walk_const_arg<'v, V: Visitor<'v>>( ConstArgKind::Path(qpath) => visitor.visit_qpath(qpath, *hir_id, qpath.span()), ConstArgKind::Anon(anon) => visitor.visit_anon_const(*anon), ConstArgKind::Error(_) => V::Result::output(), // errors and spans are not important - ConstArgKind::Literal(..) => V::Result::output(), // FIXME(mcga) + ConstArgKind::Literal { .. } => V::Result::output(), // FIXME(mcga) } } diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index d4b9d2e359d59..a79170452fae8 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -1422,14 +1422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { LowerTypeRelativePathMode::Const, )? { TypeRelativePath::AssocItem(def_id, args) => { - if !self.tcx().is_type_const(def_id) { - let mut err = self.dcx().struct_span_err( - span, - "use of trait associated const without `#[type_const]`", - ); - err.note("the declaration in the trait must be marked with `#[type_const]`"); - return Err(err.emit()); - } + self.require_type_const_attribute(def_id, span)?; let ct = Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)); let ct = self.check_param_uses_if_mcg(ct, span, false); Ok(ct) @@ -1885,30 +1878,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { item_def_id: DefId, trait_segment: Option<&hir::PathSegment<'tcx>>, item_segment: &hir::PathSegment<'tcx>, - ) -> Const<'tcx> { - match self.lower_resolved_assoc_item_path( + ) -> Result, ErrorGuaranteed> { + let (item_def_id, item_args) = self.lower_resolved_assoc_item_path( span, opt_self_ty, item_def_id, trait_segment, item_segment, ty::AssocTag::Const, - ) { - Ok((item_def_id, item_args)) => { - if !self.tcx().is_type_const(item_def_id) { - let mut err = self.dcx().struct_span_err( - span, - "use of `const` in the type system without `#[type_const]`", - ); - err.note("the declaration must be marked with `#[type_const]`"); - return Const::new_error(self.tcx(), err.emit()); - } - - let uv = ty::UnevaluatedConst::new(item_def_id, item_args); - Const::new_unevaluated(self.tcx(), uv) - } - Err(guar) => Const::new_error(self.tcx(), guar), - } + )?; + self.require_type_const_attribute(item_def_id, span)?; + let uv = ty::UnevaluatedConst::new(item_def_id, item_args); + Ok(Const::new_unevaluated(self.tcx(), uv)) } /// Lower a [resolved][hir::QPath::Resolved] (type-level) associated item path. @@ -2396,8 +2377,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { hir::ConstArgKind::Anon(anon) => self.lower_const_arg_anon(anon), hir::ConstArgKind::Infer(()) => self.ct_infer(None, const_arg.span), hir::ConstArgKind::Error(e) => ty::Const::new_error(tcx, e), - hir::ConstArgKind::Literal(kind) => { - self.lower_const_arg_literal(&kind, ty, const_arg.span) + hir::ConstArgKind::Literal { lit, negated } => { + self.lower_const_arg_literal(&lit, negated, ty, const_arg.span) } } } @@ -2668,6 +2649,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_const_param(def_id, hir_id) } Res::Def(DefKind::Const, did) => { + if let Err(guar) = self.require_type_const_attribute(did, span) { + return Const::new_error(self.tcx(), guar); + } + assert_eq!(opt_self_ty, None); let [leading_segments @ .., segment] = path.segments else { bug!() }; let _ = self @@ -2718,6 +2703,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_segment, path.segments.last().unwrap(), ) + .unwrap_or_else(|guar| Const::new_error(tcx, guar)) } Res::Def(DefKind::Static { .. }, _) => { span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported") @@ -2804,9 +2790,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { } #[instrument(skip(self), level = "debug")] - fn lower_const_arg_literal(&self, kind: &LitKind, ty: Ty<'tcx>, span: Span) -> Const<'tcx> { + fn lower_const_arg_literal( + &self, + kind: &LitKind, + neg: bool, + ty: Ty<'tcx>, + span: Span, + ) -> Const<'tcx> { let tcx = self.tcx(); - let input = LitToConstInput { lit: *kind, ty, neg: false }; + let input = LitToConstInput { lit: *kind, ty, neg }; tcx.at(span).lit_to_const(input) } @@ -2843,6 +2835,33 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { .map(|l| tcx.at(expr.span).lit_to_const(l)) } + fn require_type_const_attribute( + &self, + def_id: DefId, + span: Span, + ) -> Result<(), ErrorGuaranteed> { + let tcx = self.tcx(); + if tcx.is_type_const(def_id) { + Ok(()) + } else { + let mut err = self + .dcx() + .struct_span_err(span, "use of `const` in the type system without `#[type_const]`"); + if def_id.is_local() { + let name = tcx.def_path_str(def_id); + err.span_suggestion( + tcx.def_span(def_id).shrink_to_lo(), + format!("add `#[type_const]` attribute to `{name}`"), + format!("#[type_const]\n"), + Applicability::MaybeIncorrect, + ); + } else { + err.note("only consts marked with `#[type_const]` may be used in types"); + } + Err(err.emit()) + } + } + fn lower_delegation_ty(&self, idx: hir::InferDelegationKind) -> Ty<'tcx> { let delegation_sig = self.tcx().inherit_sig_for_delegation_item(self.item_def_id()); match idx { diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index e0e9fe7758535..d045ec0eb6c76 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1158,9 +1158,12 @@ impl<'a> State<'a> { ConstArgKind::Anon(anon) => self.print_anon_const(anon), ConstArgKind::Error(_) => self.word("/*ERROR*/"), ConstArgKind::Infer(..) => self.word("_"), - ConstArgKind::Literal(node) => { + ConstArgKind::Literal { lit, negated } => { + if *negated { + self.word("-"); + } let span = const_arg.span; - self.print_literal(&Spanned { span, node: *node }) + self.print_literal(&Spanned { span, node: *lit }) } } } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 30f8a753b9b72..d8652539d0c51 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1439,7 +1439,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Path(..) - | hir::ConstArgKind::Literal(..) + | hir::ConstArgKind::Literal { .. } | hir::ConstArgKind::Infer(..) => true, hir::ConstArgKind::Anon(..) => false, }, diff --git a/compiler/rustc_passes/Cargo.toml b/compiler/rustc_passes/Cargo.toml index 10da57f56ecfa..b65a0ad404a53 100644 --- a/compiler/rustc_passes/Cargo.toml +++ b/compiler/rustc_passes/Cargo.toml @@ -13,7 +13,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_macros = { path = "../rustc_macros" } diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl deleted file mode 100644 index fae0052ab7a43..0000000000000 --- a/compiler/rustc_passes/messages.ftl +++ /dev/null @@ -1,576 +0,0 @@ --passes_previously_accepted = - this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - --passes_see_issue = - see issue #{$issue} for more information - -passes_abi_invalid_attribute = - `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions -passes_abi_ne = - ABIs are not compatible - left ABI = {$left} - right ABI = {$right} -passes_abi_of = - fn_abi_of({$fn_name}) = {$fn_abi} - -passes_attr_application_enum = - attribute should be applied to an enum - .label = not an enum - -passes_attr_application_struct = - attribute should be applied to a struct - .label = not a struct - -passes_attr_application_struct_enum_union = - attribute should be applied to a struct, enum, or union - .label = not a struct, enum, or union - -passes_attr_application_struct_union = - attribute should be applied to a struct or union - .label = not a struct or union - -passes_autodiff_attr = - `#[autodiff]` should be applied to a function - .label = not a function - -passes_both_ffi_const_and_pure = - `#[ffi_const]` function cannot be `#[ffi_pure]` - -passes_cannot_stabilize_deprecated = - an API can't be stabilized after it is deprecated - .label = invalid version - .item = the stability attribute annotates this item - -passes_change_fields_to_be_of_unit_type = - consider changing the { $num -> - [one] field - *[other] fields - } to be of unit type to suppress this warning while preserving the field numbering, or remove the { $num -> - [one] field - *[other] fields - } - -passes_const_continue_attr = - `#[const_continue]` should be applied to a break expression - .label = not a break expression - -passes_const_stable_not_stable = - attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]` - .label = attribute specified here - -passes_custom_mir_incompatible_dialect_and_phase = - the {$dialect} dialect is not compatible with the {$phase} phase - .dialect_span = this dialect... - .phase_span = ... is not compatible with this phase - -passes_custom_mir_phase_requires_dialect = - `dialect` key required - .phase_span = `phase` argument requires a `dialect` argument - - -passes_dead_codes = - { $multiple -> - *[true] multiple {$descr}s are - [false] { $num -> - [one] {$descr} {$name_list} is - *[other] {$descr}s {$name_list} are - } - } never {$participle} - -passes_debug_visualizer_unreadable = - couldn't read {$file}: {$error} - -passes_deprecated_annotation_has_no_effect = - this `#[deprecated]` annotation has no effect - .suggestion = remove the unnecessary deprecation attribute - -passes_deprecated_attribute = - deprecated attribute must be paired with either stable or unstable attribute - -passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls = - `#[diagnostic::on_const]` can only be applied to non-const trait impls - .label = this is a const trait impl - -passes_diagnostic_diagnostic_on_const_only_for_trait_impls = - `#[diagnostic::on_const]` can only be applied to trait impls - .label = not a trait impl - -passes_diagnostic_diagnostic_on_unimplemented_only_for_traits = - `#[diagnostic::on_unimplemented]` can only be applied to trait definitions - -passes_diagnostic_item_first_defined = - the diagnostic item is first defined here - -passes_doc_alias_bad_location = - `#[doc(alias = "...")]` isn't allowed on {$location} - -passes_doc_alias_not_an_alias = - `#[doc(alias = "{$attr_str}"]` is the same as the item's name - -passes_doc_fake_variadic_not_valid = - `#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity - -passes_doc_inline_conflict = - conflicting doc inlining attributes - .help = remove one of the conflicting attributes - -passes_doc_inline_conflict_first = - this attribute... - -passes_doc_inline_conflict_second = - {"."}..conflicts with this attribute - -passes_doc_inline_only_use = - this attribute can only be applied to a `use` item - .label = only applicable on `use` items - .not_a_use_item_label = not a `use` item - .note = read for more information - -passes_doc_keyword_attribute_empty_mod = - `#[doc({$attr_name} = "...")]` should be used on empty modules - -passes_doc_keyword_attribute_not_mod = - `#[doc({$attr_name} = "...")]` should be used on modules - -passes_doc_keyword_only_impl = - `#[doc(keyword = "...")]` should be used on impl blocks - -passes_doc_masked_not_extern_crate_self = - this attribute cannot be applied to an `extern crate self` item - .label = not applicable on `extern crate self` items - .extern_crate_self_label = `extern crate self` defined here - -passes_doc_masked_only_extern_crate = - this attribute can only be applied to an `extern crate` item - .label = only applicable on `extern crate` items - .not_an_extern_crate_label = not an `extern crate` item - .note = read for more information - -passes_doc_rust_logo = - the `#[doc(rust_logo)]` attribute is used for Rust branding - -passes_doc_search_unbox_invalid = - `#[doc(search_unbox)]` should be used on generic structs and enums - -passes_duplicate_diagnostic_item_in_crate = - duplicate diagnostic item in crate `{$crate_name}`: `{$name}` - .note = the diagnostic item is first defined in crate `{$orig_crate_name}` - -passes_duplicate_eii_impls = - multiple implementations of `#[{$name}]` - .first = first implemented here in crate `{$first_crate}` - .second = also implemented here in crate `{$second_crate}` - .note = in addition to these two, { $num_additional_crates -> - [one] another implementation was found in crate {$additional_crate_names} - *[other] more implementations were also found in the following crates: {$additional_crate_names} - } - - .help = an "externally implementable item" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict - -passes_duplicate_feature_err = - the feature `{$feature}` has already been enabled - -passes_duplicate_lang_item = - found duplicate lang item `{$lang_item_name}` - .first_defined_span = the lang item is first defined here - .first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on) - .first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}` - .first_definition_local = first definition in the local crate (`{$orig_crate_name}`) - .second_definition_local = second definition in the local crate (`{$crate_name}`) - .first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path} - .second_definition_path = second definition in `{$crate_name}` loaded from {$path} - -passes_duplicate_lang_item_crate = - duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}` - .first_defined_span = the lang item is first defined here - .first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on) - .first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}` - .first_definition_local = first definition in the local crate (`{$orig_crate_name}`) - .second_definition_local = second definition in the local crate (`{$crate_name}`) - .first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path} - .second_definition_path = second definition in `{$crate_name}` loaded from {$path} - -passes_duplicate_lang_item_crate_depends = - duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}` - .first_defined_span = the lang item is first defined here - .first_defined_crate_depends = the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on) - .first_defined_crate = the lang item is first defined in crate `{$orig_crate_name}` - .first_definition_local = first definition in the local crate (`{$orig_crate_name}`) - .second_definition_local = second definition in the local crate (`{$crate_name}`) - .first_definition_path = first definition in `{$orig_crate_name}` loaded from {$orig_path} - .second_definition_path = second definition in `{$crate_name}` loaded from {$path} - -passes_eii_fn_with_track_caller = - `#[{$name}]` is not allowed to have `#[track_caller]` - .label = `#[{$name}]` is not allowed to have `#[track_caller]` - -passes_eii_impl_not_function = - `eii_macro_for` is only valid on functions - -passes_eii_impl_requires_unsafe = - `#[{$name}]` is unsafe to implement -passes_eii_impl_requires_unsafe_suggestion = wrap the attribute in `unsafe(...)` - -passes_eii_without_impl = - `#[{$name}]` required, but not found - .label = expected because `#[{$name}]` was declared here in crate `{$decl_crate_name}` - .help = expected at least one implementation in crate `{$current_crate_name}` or any of its dependencies - -passes_enum_variant_same_name = - it is impossible to refer to the {$dead_descr} `{$dead_name}` because it is shadowed by this enum variant with the same name - -passes_extern_main = - the `main` function cannot be declared in an `extern` block - -passes_feature_previously_declared = - feature `{$feature}` is declared {$declared}, but was previously declared {$prev_declared} - -passes_feature_stable_twice = - feature `{$feature}` is declared stable since {$since}, but was previously declared stable since {$prev_since} - -passes_function_not_found_in_trait = function not found in this trait - -passes_function_not_have_default_implementation = function doesn't have a default implementation - .note = required by this annotation - -passes_functions_names_duplicated = functions names are duplicated - .note = all `#[rustc_must_implement_one_of]` arguments must be unique - -passes_ignored_derived_impls = - `{$name}` has {$trait_list_len -> - [one] a derived impl - *[other] derived impls - } for the {$trait_list_len -> - [one] trait {$trait_list}, but this is - *[other] traits {$trait_list}, but these are - } intentionally ignored during dead code analysis - -passes_implied_feature_not_exist = - feature `{$implied_by}` implying `{$feature}` does not exist - -passes_incorrect_crate_type = lang items are not allowed in stable dylibs - -passes_incorrect_do_not_recommend_location = - `#[diagnostic::do_not_recommend]` can only be placed on trait implementations - -passes_incorrect_target = - `{$name}` lang item must be applied to a {$kind} with {$at_least -> - [true] at least {$num} - *[false] {$num} - } generic {$num -> - [one] argument - *[other] arguments - } - .label = this {$kind} has {$actual_num} generic {$actual_num -> - [one] argument - *[other] arguments - } - -passes_ineffective_unstable_impl = an `#[unstable]` annotation here has no effect - .note = see issue #55436 for more information - -passes_inline_ignored_for_exported = - `#[inline]` is ignored on externally exported functions - .help = externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]` - -passes_inner_crate_level_attr = - crate-level attribute should be in the root module - -passes_invalid_attr_at_crate_level = - `{$name}` attribute cannot be used at crate level - .suggestion = perhaps you meant to use an outer attribute - -passes_invalid_attr_at_crate_level_item = - the inner attribute doesn't annotate this {$kind} - -passes_lang_item_fn = {$name -> - [panic_impl] `#[panic_handler]` - *[other] `{$name}` lang item -} function - -passes_lang_item_fn_with_target_feature = - {passes_lang_item_fn} is not allowed to have `#[target_feature]` - .label = {passes_lang_item_fn} is not allowed to have `#[target_feature]` - -passes_lang_item_fn_with_track_caller = - {passes_lang_item_fn} is not allowed to have `#[track_caller]` - .label = {passes_lang_item_fn} is not allowed to have `#[track_caller]` - -passes_lang_item_on_incorrect_target = - `{$name}` lang item must be applied to a {$expected_target} - .label = attribute should be applied to a {$expected_target}, not a {$actual_target} - -passes_layout_abi = - abi: {$abi} -passes_layout_align = - align: {$align} -passes_layout_homogeneous_aggregate = - homogeneous_aggregate: {$homogeneous_aggregate} -passes_layout_of = - layout_of({$normalized_ty}) = {$ty_layout} -passes_layout_size = - size: {$size} - -passes_link = - attribute should be applied to an `extern` block with non-Rust ABI - .warn = {-passes_previously_accepted} - .label = not an `extern` block - -passes_loop_match_attr = - `#[loop_match]` should be applied to a loop - .label = not a loop - -passes_macro_export_on_decl_macro = - `#[macro_export]` has no effect on declarative macro definitions - .note = declarative macros follow the same exporting rules as regular items - -passes_macro_only_attribute = - attribute should be applied to a macro - .label = not a macro - -passes_may_dangle = - `#[may_dangle]` must be applied to a lifetime or type generic parameter in `Drop` impl - -passes_missing_const_err = - attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const` - .help = make the function or method const - -passes_missing_const_stab_attr = - {$descr} has missing const stability attribute - -passes_missing_lang_item = - lang item required, but not found: `{$name}` - .note = this can occur when a binary crate with `#![no_std]` is compiled for a target where `{$name}` is defined in the standard library - .help = you may be able to compile for a target that doesn't need `{$name}`, specify a target with `--target` or in `.cargo/config` - -passes_missing_panic_handler = - `#[panic_handler]` function required, but not found - -passes_missing_stability_attr = - {$descr} has missing stability attribute - -passes_misspelled_feature = there is a feature with a similar name: `{$actual_name}` - -passes_mixed_export_name_and_no_mangle = `{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}` - .label = `{$no_mangle_attr}` is ignored - .note = `{$export_name_attr}` takes precedence - .suggestion = remove the `{$no_mangle_attr}` attribute - -passes_multiple_rustc_main = - multiple functions with a `#[rustc_main]` attribute - .first = first `#[rustc_main]` function - .additional = additional `#[rustc_main]` function - -passes_must_implement_not_function = not a function - -passes_must_implement_not_function_note = all `#[rustc_must_implement_one_of]` arguments must be associated function names - -passes_must_implement_not_function_span_note = required by this annotation - -passes_no_main_function = - `main` function not found in crate `{$crate_name}` - .here_is_main = here is a function named `main` - .one_or_more_possible_main = you have one or more functions named `main` not defined at the crate level - .consider_moving_main = consider moving the `main` function definitions - .main_must_be_defined_at_crate = the main function must be defined at the crate level{$has_filename -> - [true] {" "}(in `{$filename}`) - *[false] {""} - } - .consider_adding_main_to_file = consider adding a `main` function to `{$filename}` - .consider_adding_main_at_crate = consider adding a `main` function at the crate level - .teach_note = if you don't know the basics of Rust, you can go look to the Rust Book to get started: https://doc.rust-lang.org/book/ - .non_function_main = non-function item at `crate::main` is found - -passes_non_exhaustive_with_default_field_values = - `#[non_exhaustive]` can't be used to annotate items with default field values - .label = this struct has default field values - -passes_non_exported_macro_invalid_attrs = - attribute should be applied to function or closure - .label = not a function or closure - -passes_object_lifetime_err = - {$repr} - -passes_outer_crate_level_attr = - crate-level attribute should be an inner attribute - -passes_outer_crate_level_attr_suggestion = - add a `!` - -passes_panic_unwind_without_std = - unwinding panics are not supported without std - .note = since the core library is usually precompiled with panic="unwind", rebuilding your crate with panic="abort" may not be enough to fix the problem - .help = using nightly cargo, use -Zbuild-std with panic="abort" to avoid unwinding - -passes_parent_info = - {$num -> - [one] {$descr} - *[other] {$descr}s - } in this {$parent_descr} - -passes_proc_macro_bad_sig = {$kind} has incorrect signature - -passes_remove_fields = - consider removing { $num -> - [one] this - *[other] these - } { $num -> - [one] field - *[other] fields - } - -passes_repr_align_greater_than_target_max = - alignment must not be greater than `isize::MAX` bytes - .note = `isize::MAX` is {$size} for the current target - -passes_repr_align_should_be_align = - `#[repr(align(...))]` is not supported on {$item} - .help = use `#[rustc_align(...)]` instead - -passes_repr_align_should_be_align_static = - `#[repr(align(...))]` is not supported on {$item} - .help = use `#[rustc_align_static(...)]` instead - -passes_repr_conflicting = - conflicting representation hints - -passes_rustc_allow_const_fn_unstable = - attribute should be applied to `const fn` - .label = not a `const fn` - -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_force_inline_coro = - attribute cannot be applied to a `async`, `gen` or `async gen` function - .label = `async`, `gen` or `async gen` function - -passes_rustc_legacy_const_generics_index = - #[rustc_legacy_const_generics] must have one index for each generic parameter - .label = generic parameters - -passes_rustc_legacy_const_generics_index_exceed = - index exceeds number of arguments - .label = there {$arg_count -> - [one] is - *[other] are - } only {$arg_count} {$arg_count -> - [one] argument - *[other] arguments - } - -passes_rustc_legacy_const_generics_only = - #[rustc_legacy_const_generics] functions must only have const generics - .label = non-const generic parameter - - -passes_rustc_pub_transparent = - attribute should be applied to `#[repr(transparent)]` types - .label = not a `#[repr(transparent)]` type - -passes_sanitize_attribute_not_allowed = - sanitize attribute not allowed here - .not_fn_impl_mod = not a function, impl block, or module - .no_body = function has no body - .help = sanitize attribute can be applied to a function (with body), impl block, or module - -passes_trait_impl_const_stability_mismatch = const stability on the impl does not match the const stability on the trait -passes_trait_impl_const_stability_mismatch_impl_stable = this impl is (implicitly) stable... -passes_trait_impl_const_stability_mismatch_impl_unstable = this impl is unstable... -passes_trait_impl_const_stability_mismatch_trait_stable = ...but the trait is stable -passes_trait_impl_const_stability_mismatch_trait_unstable = ...but the trait is unstable - -passes_trait_impl_const_stable = - trait implementations cannot be const stable yet - .note = see issue #143874 for more information - -passes_transparent_incompatible = - transparent {$target} cannot have other repr hints - -passes_unexportable_adt_with_private_fields = ADT types with private fields are not exportable - .note = `{$field_name}` is private - -passes_unexportable_fn_abi = only functions with "C" ABI are exportable - -passes_unexportable_generic_fn = generic functions are not exportable - -passes_unexportable_item = {$descr}'s are not exportable - -passes_unexportable_priv_item = private items are not exportable - .note = is only usable at visibility `{$vis_descr}` - -passes_unexportable_type_in_interface = {$desc} with `#[export_stable]` attribute uses type `{$ty}`, which is not exportable - .label = not exportable - -passes_unexportable_type_repr = types with unstable layout are not exportable - -passes_unknown_external_lang_item = - unknown external lang item: `{$lang_item}` - -passes_unknown_feature = - unknown feature `{$feature}` - -passes_unknown_feature_alias = - feature `{$alias}` has been renamed to `{$feature}` - -passes_unknown_lang_item = - definition of an unknown lang item: `{$name}` - .label = definition of unknown lang item `{$name}` - -passes_unnecessary_partial_stable_feature = the feature `{$feature}` has been partially stabilized since {$since} and is succeeded by the feature `{$implies}` - .suggestion = if you are using features which are still unstable, change to using `{$implies}` - .suggestion_remove = if you are using features which are now stable, remove this line - -passes_unnecessary_stable_feature = the feature `{$feature}` has been stable since {$since} and no longer requires an attribute to enable - -passes_unrecognized_argument = - unrecognized argument - -passes_unstable_attr_for_already_stable_feature = - can't mark as unstable using an already stable feature - .label = this feature is already stable - .item = the stability attribute annotates this item - .help = consider removing the attribute - -passes_unsupported_attributes_in_where = - most attributes are not supported in `where` clauses - .help = only `#[cfg]` and `#[cfg_attr]` are supported - -passes_unused = - unused attribute - .suggestion = remove this attribute - -passes_unused_default_method_body_const_note = - `default_method_body_is_const` has been replaced with `const` on traits - -passes_unused_duplicate = - unused attribute - .suggestion = remove this attribute - .note = attribute also specified here - .warn = {-passes_previously_accepted} - -passes_unused_empty_lints_note = - attribute `{$name}` with an empty list has no effect - -passes_unused_linker_messages_note = - the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked - -passes_unused_multiple = - multiple `{$name}` attributes - .suggestion = remove this attribute - .note = attribute also specified here - -passes_unused_no_lints_note = - attribute `{$name}` without any lints has no effect - -passes_useless_assignment = - useless assignment of {$is_field_assign -> - [true] field - *[false] variable - } of type `{$ty}` to itself - -passes_useless_stability = - this stability annotation is useless - .label = useless stability annotation - .item = the stability attribute annotates this item diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index c8980e4aadc7e..c207d7455f749 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -15,7 +15,7 @@ use rustc_attr_parsing::{AttributeParser, Late}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::thin_vec::ThinVec; use rustc_data_structures::unord::UnordMap; -use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey}; +use rustc_errors::{DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey, inline_fluent}; use rustc_feature::{ ACCEPTED_LANG_FEATURES, AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute, @@ -54,23 +54,23 @@ use rustc_trait_selection::infer::{TyCtxtInferExt, ValuePairs}; use rustc_trait_selection::traits::ObligationCtxt; use tracing::debug; -use crate::{errors, fluent_generated as fluent}; +use crate::errors; #[derive(LintDiagnostic)] -#[diag(passes_diagnostic_diagnostic_on_unimplemented_only_for_traits)] +#[diag("`#[diagnostic::on_unimplemented]` can only be applied to trait definitions")] struct DiagnosticOnUnimplementedOnlyForTraits; #[derive(LintDiagnostic)] -#[diag(passes_diagnostic_diagnostic_on_const_only_for_trait_impls)] +#[diag("`#[diagnostic::on_const]` can only be applied to trait impls")] struct DiagnosticOnConstOnlyForTraitImpls { - #[label] + #[label("not a trait impl")] item_span: Span, } #[derive(LintDiagnostic)] -#[diag(passes_diagnostic_diagnostic_on_const_only_for_non_const_trait_impls)] +#[diag("`#[diagnostic::on_const]` can only be applied to non-const trait impls")] struct DiagnosticOnConstOnlyForNonConstTraitImpls { - #[label] + #[label("this is a const trait impl")] item_span: Span, } @@ -1010,8 +1010,11 @@ impl<'tcx> CheckAttrVisitor<'tcx> { for (inline2, span2) in rest { if inline2 != inline { let mut spans = MultiSpan::from_spans(vec![*span, *span2]); - spans.push_span_label(*span, fluent::passes_doc_inline_conflict_first); - spans.push_span_label(*span2, fluent::passes_doc_inline_conflict_second); + spans.push_span_label(*span, inline_fluent!("this attribute...")); + spans.push_span_label( + *span2, + inline_fluent!("{\".\"}..conflicts with this attribute"), + ); self.dcx().emit_err(errors::DocInlineConflict { spans }); return; } @@ -1155,7 +1158,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { &self.tcx.sess, sym::rustdoc_internals, *span, - fluent::passes_doc_rust_logo, + inline_fluent!("the `#[doc(rust_logo)]` attribute is used for Rust branding"), ) .emit(); } diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index d0fa1c4f0e037..90b4d1b32bf7b 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -4,7 +4,7 @@ use std::path::{Path, PathBuf}; use rustc_errors::codes::*; use rustc_errors::{ Applicability, Diag, DiagCtxtHandle, DiagSymbolList, Diagnostic, EmissionGuarantee, Level, - MultiSpan, + MultiSpan, inline_fluent, }; use rustc_hir::Target; use rustc_hir::attrs::{MirDialect, MirPhase}; @@ -13,80 +13,84 @@ use rustc_middle::ty::{MainDefinition, Ty}; use rustc_span::{DUMMY_SP, Span, Symbol}; use crate::check_attr::ProcMacroKind; -use crate::fluent_generated as fluent; use crate::lang_items::Duplicate; #[derive(LintDiagnostic)] -#[diag(passes_incorrect_do_not_recommend_location)] +#[diag("`#[diagnostic::do_not_recommend]` can only be placed on trait implementations")] pub(crate) struct IncorrectDoNotRecommendLocation; #[derive(Diagnostic)] -#[diag(passes_autodiff_attr)] +#[diag("`#[autodiff]` should be applied to a function")] pub(crate) struct AutoDiffAttr { #[primary_span] - #[label] + #[label("not a function")] pub attr_span: Span, } #[derive(Diagnostic)] -#[diag(passes_loop_match_attr)] +#[diag("`#[loop_match]` should be applied to a loop")] pub(crate) struct LoopMatchAttr { #[primary_span] pub attr_span: Span, - #[label] + #[label("not a loop")] pub node_span: Span, } #[derive(Diagnostic)] -#[diag(passes_const_continue_attr)] +#[diag("`#[const_continue]` should be applied to a break expression")] pub(crate) struct ConstContinueAttr { #[primary_span] pub attr_span: Span, - #[label] + #[label("not a break expression")] pub node_span: Span, } #[derive(LintDiagnostic)] -#[diag(passes_mixed_export_name_and_no_mangle)] +#[diag("`{$no_mangle_attr}` attribute may not be used in combination with `{$export_name_attr}`")] pub(crate) struct MixedExportNameAndNoMangle { - #[label] - #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")] + #[label("`{$no_mangle_attr}` is ignored")] + #[suggestion( + "remove the `{$no_mangle_attr}` attribute", + style = "verbose", + code = "", + applicability = "machine-applicable" + )] pub no_mangle_span: Span, - #[note] + #[note("`{$export_name_attr}` takes precedence")] pub export_name_span: Span, pub no_mangle_attr: &'static str, pub export_name_attr: &'static str, } #[derive(LintDiagnostic)] -#[diag(passes_outer_crate_level_attr)] +#[diag("crate-level attribute should be an inner attribute")] pub(crate) struct OuterCrateLevelAttr { #[subdiagnostic] pub suggestion: OuterCrateLevelAttrSuggestion, } #[derive(Subdiagnostic)] -#[multipart_suggestion(passes_outer_crate_level_attr_suggestion, style = "verbose")] +#[multipart_suggestion("add a `!`", style = "verbose")] pub(crate) struct OuterCrateLevelAttrSuggestion { #[suggestion_part(code = "!")] pub bang_position: Span, } #[derive(LintDiagnostic)] -#[diag(passes_inner_crate_level_attr)] +#[diag("crate-level attribute should be in the root module")] pub(crate) struct InnerCrateLevelAttr; #[derive(Diagnostic)] -#[diag(passes_non_exhaustive_with_default_field_values)] +#[diag("`#[non_exhaustive]` can't be used to annotate items with default field values")] pub(crate) struct NonExhaustiveWithDefaultFieldValues { #[primary_span] pub attr_span: Span, - #[label] + #[label("this struct has default field values")] pub defn_span: Span, } #[derive(Diagnostic)] -#[diag(passes_doc_alias_bad_location)] +#[diag("`#[doc(alias = \"...\")]` isn't allowed on {$location}")] pub(crate) struct DocAliasBadLocation<'a> { #[primary_span] pub span: Span, @@ -94,7 +98,7 @@ pub(crate) struct DocAliasBadLocation<'a> { } #[derive(Diagnostic)] -#[diag(passes_doc_alias_not_an_alias)] +#[diag("`#[doc(alias = \"{$attr_str}\"]` is the same as the item's name")] pub(crate) struct DocAliasNotAnAlias { #[primary_span] pub span: Span, @@ -102,7 +106,7 @@ pub(crate) struct DocAliasNotAnAlias { } #[derive(Diagnostic)] -#[diag(passes_doc_keyword_attribute_empty_mod)] +#[diag("`#[doc({$attr_name} = \"...\")]` should be used on empty modules")] pub(crate) struct DocKeywordAttributeEmptyMod { #[primary_span] pub span: Span, @@ -110,7 +114,7 @@ pub(crate) struct DocKeywordAttributeEmptyMod { } #[derive(Diagnostic)] -#[diag(passes_doc_keyword_attribute_not_mod)] +#[diag("`#[doc({$attr_name} = \"...\")]` should be used on modules")] pub(crate) struct DocKeywordAttributeNotMod { #[primary_span] pub span: Span, @@ -118,115 +122,131 @@ pub(crate) struct DocKeywordAttributeNotMod { } #[derive(Diagnostic)] -#[diag(passes_doc_fake_variadic_not_valid)] +#[diag( + "`#[doc(fake_variadic)]` must be used on the first of a set of tuple or fn pointer trait impls with varying arity" +)] pub(crate) struct DocFakeVariadicNotValid { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_doc_keyword_only_impl)] +#[diag("`#[doc(keyword = \"...\")]` should be used on impl blocks")] pub(crate) struct DocKeywordOnlyImpl { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_doc_search_unbox_invalid)] +#[diag("`#[doc(search_unbox)]` should be used on generic structs and enums")] pub(crate) struct DocSearchUnboxInvalid { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_doc_inline_conflict)] -#[help] +#[diag("conflicting doc inlining attributes")] +#[help("remove one of the conflicting attributes")] pub(crate) struct DocInlineConflict { #[primary_span] pub spans: MultiSpan, } #[derive(LintDiagnostic)] -#[diag(passes_doc_inline_only_use)] -#[note] +#[diag("this attribute can only be applied to a `use` item")] +#[note( + "read for more information" +)] pub(crate) struct DocInlineOnlyUse { - #[label] + #[label("only applicable on `use` items")] pub attr_span: Span, - #[label(passes_not_a_use_item_label)] + #[label("not a `use` item")] pub item_span: Span, } #[derive(LintDiagnostic)] -#[diag(passes_doc_masked_only_extern_crate)] -#[note] +#[diag("this attribute can only be applied to an `extern crate` item")] +#[note( + "read for more information" +)] pub(crate) struct DocMaskedOnlyExternCrate { - #[label] + #[label("only applicable on `extern crate` items")] pub attr_span: Span, - #[label(passes_not_an_extern_crate_label)] + #[label("not an `extern crate` item")] pub item_span: Span, } #[derive(LintDiagnostic)] -#[diag(passes_doc_masked_not_extern_crate_self)] +#[diag("this attribute cannot be applied to an `extern crate self` item")] pub(crate) struct DocMaskedNotExternCrateSelf { - #[label] + #[label("not applicable on `extern crate self` items")] pub attr_span: Span, - #[label(passes_extern_crate_self_label)] + #[label("`extern crate self` defined here")] pub item_span: Span, } #[derive(Diagnostic)] -#[diag(passes_both_ffi_const_and_pure, code = E0757)] +#[diag("`#[ffi_const]` function cannot be `#[ffi_pure]`", code = E0757)] pub(crate) struct BothFfiConstAndPure { #[primary_span] pub attr_span: Span, } #[derive(LintDiagnostic)] -#[diag(passes_link)] -#[warning] +#[diag("attribute should be applied to an `extern` block with non-Rust ABI")] +#[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" +)] pub(crate) struct Link { - #[label] + #[label("not an `extern` block")] pub span: Option, } #[derive(Diagnostic)] -#[diag(passes_rustc_legacy_const_generics_only)] +#[diag("#[rustc_legacy_const_generics] functions must only have const generics")] pub(crate) struct RustcLegacyConstGenericsOnly { #[primary_span] pub attr_span: Span, - #[label] + #[label("non-const generic parameter")] pub param_span: Span, } #[derive(Diagnostic)] -#[diag(passes_rustc_legacy_const_generics_index)] +#[diag("#[rustc_legacy_const_generics] must have one index for each generic parameter")] pub(crate) struct RustcLegacyConstGenericsIndex { #[primary_span] pub attr_span: Span, - #[label] + #[label("generic parameters")] pub generics_span: Span, } #[derive(Diagnostic)] -#[diag(passes_rustc_legacy_const_generics_index_exceed)] +#[diag("index exceeds number of arguments")] pub(crate) struct RustcLegacyConstGenericsIndexExceed { #[primary_span] - #[label] + #[label( + "there {$arg_count -> + [one] is + *[other] are + } only {$arg_count} {$arg_count -> + [one] argument + *[other] arguments + }" + )] pub span: Span, pub arg_count: usize, } #[derive(Diagnostic)] -#[diag(passes_repr_conflicting, code = E0566)] +#[diag("conflicting representation hints", code = E0566)] pub(crate) struct ReprConflicting { #[primary_span] pub hint_spans: Vec, } #[derive(Diagnostic)] -#[diag(passes_repr_align_greater_than_target_max, code = E0589)] -#[note] +#[diag("alignment must not be greater than `isize::MAX` bytes", code = E0589)] +#[note("`isize::MAX` is {$size} for the current target")] pub(crate) struct InvalidReprAlignForTarget { #[primary_span] pub span: Span, @@ -234,20 +254,20 @@ pub(crate) struct InvalidReprAlignForTarget { } #[derive(LintDiagnostic)] -#[diag(passes_repr_conflicting, code = E0566)] +#[diag("conflicting representation hints", code = E0566)] pub(crate) struct ReprConflictingLint; #[derive(Diagnostic)] -#[diag(passes_macro_only_attribute)] +#[diag("attribute should be applied to a macro")] pub(crate) struct MacroOnlyAttribute { #[primary_span] pub attr_span: Span, - #[label] + #[label("not a macro")] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_debug_visualizer_unreadable)] +#[diag("couldn't read {$file}: {$error}")] pub(crate) struct DebugVisualizerUnreadable<'a> { #[primary_span] pub span: Span, @@ -256,106 +276,114 @@ pub(crate) struct DebugVisualizerUnreadable<'a> { } #[derive(Diagnostic)] -#[diag(passes_rustc_allow_const_fn_unstable)] +#[diag("attribute should be applied to `const fn`")] pub(crate) struct RustcAllowConstFnUnstable { #[primary_span] pub attr_span: Span, - #[label] + #[label("not a `const fn`")] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_rustc_pub_transparent)] +#[diag("attribute should be applied to `#[repr(transparent)]` types")] pub(crate) struct RustcPubTransparent { #[primary_span] pub attr_span: Span, - #[label] + #[label("not a `#[repr(transparent)]` type")] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_rustc_force_inline_coro)] +#[diag("attribute cannot be applied to a `async`, `gen` or `async gen` function")] pub(crate) struct RustcForceInlineCoro { #[primary_span] pub attr_span: Span, - #[label] + #[label("`async`, `gen` or `async gen` function")] pub span: Span, } #[derive(LintDiagnostic)] pub(crate) enum MacroExport { - #[diag(passes_macro_export_on_decl_macro)] - #[note] + #[diag("`#[macro_export]` has no effect on declarative macro definitions")] + #[note("declarative macros follow the same exporting rules as regular items")] OnDeclMacro, } #[derive(Subdiagnostic)] pub(crate) enum UnusedNote { - #[note(passes_unused_empty_lints_note)] + #[note("attribute `{$name}` with an empty list has no effect")] EmptyList { name: Symbol }, - #[note(passes_unused_no_lints_note)] + #[note("attribute `{$name}` without any lints has no effect")] NoLints { name: Symbol }, - #[note(passes_unused_default_method_body_const_note)] + #[note("`default_method_body_is_const` has been replaced with `const` on traits")] DefaultMethodBodyConst, - #[note(passes_unused_linker_messages_note)] + #[note( + "the `linker_messages` lint can only be controlled at the root of a crate that needs to be linked" + )] LinkerMessagesBinaryCrateOnly, } #[derive(LintDiagnostic)] -#[diag(passes_unused)] +#[diag("unused attribute")] pub(crate) struct Unused { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] pub attr_span: Span, #[subdiagnostic] pub note: UnusedNote, } #[derive(Diagnostic)] -#[diag(passes_non_exported_macro_invalid_attrs, code = E0518)] +#[diag("attribute should be applied to function or closure", code = E0518)] pub(crate) struct NonExportedMacroInvalidAttrs { #[primary_span] - #[label] + #[label("not a function or closure")] pub attr_span: Span, } #[derive(Diagnostic)] -#[diag(passes_may_dangle)] +#[diag("`#[may_dangle]` must be applied to a lifetime or type generic parameter in `Drop` impl")] pub(crate) struct InvalidMayDangle { #[primary_span] pub attr_span: Span, } #[derive(LintDiagnostic)] -#[diag(passes_unused_duplicate)] +#[diag("unused attribute")] pub(crate) struct UnusedDuplicate { - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] pub this: Span, - #[note] + #[note("attribute also specified here")] pub other: Span, - #[warning] + #[warning( + "this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!" + )] pub warning: bool, } #[derive(Diagnostic)] -#[diag(passes_unused_multiple)] +#[diag("multiple `{$name}` attributes")] pub(crate) struct UnusedMultiple { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable")] + #[suggestion("remove this attribute", code = "", applicability = "machine-applicable")] pub this: Span, - #[note] + #[note("attribute also specified here")] pub other: Span, pub name: Symbol, } #[derive(LintDiagnostic)] -#[diag(passes_deprecated_annotation_has_no_effect)] +#[diag("this `#[deprecated]` annotation has no effect")] pub(crate) struct DeprecatedAnnotationHasNoEffect { - #[suggestion(applicability = "machine-applicable", code = "")] + #[suggestion( + "remove the unnecessary deprecation attribute", + applicability = "machine-applicable", + code = "" + )] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_unknown_external_lang_item, code = E0264)] +#[diag("unknown external lang item: `{$lang_item}`", code = E0264)] pub(crate) struct UnknownExternLangItem { #[primary_span] pub span: Span, @@ -363,48 +391,74 @@ pub(crate) struct UnknownExternLangItem { } #[derive(Diagnostic)] -#[diag(passes_missing_panic_handler)] +#[diag("`#[panic_handler]` function required, but not found")] pub(crate) struct MissingPanicHandler; #[derive(Diagnostic)] -#[diag(passes_panic_unwind_without_std)] -#[help] -#[note] +#[diag("unwinding panics are not supported without std")] +#[help("using nightly cargo, use -Zbuild-std with panic=\"abort\" to avoid unwinding")] +#[note( + "since the core library is usually precompiled with panic=\"unwind\", rebuilding your crate with panic=\"abort\" may not be enough to fix the problem" +)] pub(crate) struct PanicUnwindWithoutStd; #[derive(Diagnostic)] -#[diag(passes_missing_lang_item)] -#[note] -#[help] +#[diag("lang item required, but not found: `{$name}`")] +#[note( + "this can occur when a binary crate with `#![no_std]` is compiled for a target where `{$name}` is defined in the standard library" +)] +#[help( + "you may be able to compile for a target that doesn't need `{$name}`, specify a target with `--target` or in `.cargo/config`" +)] pub(crate) struct MissingLangItem { pub name: Symbol, } #[derive(Diagnostic)] -#[diag(passes_lang_item_fn_with_track_caller)] +#[diag( + "{$name -> + [panic_impl] `#[panic_handler]` + *[other] `{$name}` lang item +} function is not allowed to have `#[track_caller]`" +)] pub(crate) struct LangItemWithTrackCaller { #[primary_span] pub attr_span: Span, pub name: Symbol, - #[label] + #[label( + "{$name -> + [panic_impl] `#[panic_handler]` + *[other] `{$name}` lang item + } function is not allowed to have `#[track_caller]`" + )] pub sig_span: Span, } #[derive(Diagnostic)] -#[diag(passes_lang_item_fn_with_target_feature)] +#[diag( + "{$name -> + [panic_impl] `#[panic_handler]` + *[other] `{$name}` lang item + } function is not allowed to have `#[target_feature]`" +)] pub(crate) struct LangItemWithTargetFeature { #[primary_span] pub attr_span: Span, pub name: Symbol, - #[label] + #[label( + "{$name -> + [panic_impl] `#[panic_handler]` + *[other] `{$name}` lang item + } function is not allowed to have `#[target_feature]`" + )] pub sig_span: Span, } #[derive(Diagnostic)] -#[diag(passes_lang_item_on_incorrect_target, code = E0718)] +#[diag("`{$name}` lang item must be applied to a {$expected_target}", code = E0718)] pub(crate) struct LangItemOnIncorrectTarget { #[primary_span] - #[label] + #[label("attribute should be applied to a {$expected_target}, not a {$actual_target}")] pub span: Span, pub name: Symbol, pub expected_target: Target, @@ -412,10 +466,10 @@ pub(crate) struct LangItemOnIncorrectTarget { } #[derive(Diagnostic)] -#[diag(passes_unknown_lang_item, code = E0522)] +#[diag("definition of an unknown lang item: `{$name}`", code = E0522)] pub(crate) struct UnknownLangItem { #[primary_span] - #[label] + #[label("definition of unknown lang item `{$name}`")] pub span: Span, pub name: Symbol, } @@ -436,7 +490,11 @@ pub(crate) struct ItemFollowingInnerAttr { impl Diagnostic<'_, G> for InvalidAttrAtCrateLevel { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { - let mut diag = Diag::new(dcx, level, fluent::passes_invalid_attr_at_crate_level); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("`{$name}` attribute cannot be used at crate level"), + ); diag.span(self.span); diag.arg("name", self.name); // Only emit an error with a suggestion if we can create a string out @@ -444,27 +502,30 @@ impl Diagnostic<'_, G> for InvalidAttrAtCrateLevel { if let Some(span) = self.sugg_span { diag.span_suggestion_verbose( span, - fluent::passes_suggestion, + inline_fluent!("perhaps you meant to use an outer attribute"), String::new(), Applicability::MachineApplicable, ); } if let Some(item) = self.item { diag.arg("kind", item.kind); - diag.span_label(item.span, fluent::passes_invalid_attr_at_crate_level_item); + diag.span_label( + item.span, + inline_fluent!("the inner attribute doesn't annotate this {$kind}"), + ); } diag } } #[derive(Diagnostic)] -#[diag(passes_duplicate_diagnostic_item_in_crate)] +#[diag("duplicate diagnostic item in crate `{$crate_name}`: `{$name}`")] pub(crate) struct DuplicateDiagnosticItemInCrate { #[primary_span] pub duplicate_span: Option, - #[note(passes_diagnostic_item_first_defined)] + #[note("the diagnostic item is first defined here")] pub orig_span: Option, - #[note] + #[note("the diagnostic item is first defined in crate `{$orig_crate_name}`")] pub different_crates: bool, pub crate_name: Symbol, pub orig_crate_name: Symbol, @@ -472,7 +533,7 @@ pub(crate) struct DuplicateDiagnosticItemInCrate { } #[derive(Diagnostic)] -#[diag(passes_layout_abi)] +#[diag("abi: {$abi}")] pub(crate) struct LayoutAbi { #[primary_span] pub span: Span, @@ -480,7 +541,7 @@ pub(crate) struct LayoutAbi { } #[derive(Diagnostic)] -#[diag(passes_layout_align)] +#[diag("align: {$align}")] pub(crate) struct LayoutAlign { #[primary_span] pub span: Span, @@ -488,7 +549,7 @@ pub(crate) struct LayoutAlign { } #[derive(Diagnostic)] -#[diag(passes_layout_size)] +#[diag("size: {$size}")] pub(crate) struct LayoutSize { #[primary_span] pub span: Span, @@ -496,7 +557,7 @@ pub(crate) struct LayoutSize { } #[derive(Diagnostic)] -#[diag(passes_layout_homogeneous_aggregate)] +#[diag("homogeneous_aggregate: {$homogeneous_aggregate}")] pub(crate) struct LayoutHomogeneousAggregate { #[primary_span] pub span: Span, @@ -504,7 +565,7 @@ pub(crate) struct LayoutHomogeneousAggregate { } #[derive(Diagnostic)] -#[diag(passes_layout_of)] +#[diag("layout_of({$normalized_ty}) = {$ty_layout}")] pub(crate) struct LayoutOf<'tcx> { #[primary_span] pub span: Span, @@ -513,7 +574,7 @@ pub(crate) struct LayoutOf<'tcx> { } #[derive(Diagnostic)] -#[diag(passes_abi_of)] +#[diag("fn_abi_of({$fn_name}) = {$fn_abi}")] pub(crate) struct AbiOf { #[primary_span] pub span: Span, @@ -522,7 +583,11 @@ pub(crate) struct AbiOf { } #[derive(Diagnostic)] -#[diag(passes_abi_ne)] +#[diag( + "ABIs are not compatible + left ABI = {$left} + right ABI = {$right}" +)] pub(crate) struct AbiNe { #[primary_span] pub span: Span, @@ -531,21 +596,23 @@ pub(crate) struct AbiNe { } #[derive(Diagnostic)] -#[diag(passes_abi_invalid_attribute)] +#[diag( + "`#[rustc_abi]` can only be applied to function items, type aliases, and associated functions" +)] pub(crate) struct AbiInvalidAttribute { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_unrecognized_argument)] +#[diag("unrecognized argument")] pub(crate) struct UnrecognizedArgument { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_feature_stable_twice, code = E0711)] +#[diag("feature `{$feature}` is declared stable since {$since}, but was previously declared stable since {$prev_since}", code = E0711)] pub(crate) struct FeatureStableTwice { #[primary_span] pub span: Span, @@ -555,7 +622,7 @@ pub(crate) struct FeatureStableTwice { } #[derive(Diagnostic)] -#[diag(passes_feature_previously_declared, code = E0711)] +#[diag("feature `{$feature}` is declared {$declared}, but was previously declared {$prev_declared}", code = E0711)] pub(crate) struct FeaturePreviouslyDeclared<'a> { #[primary_span] pub span: Span, @@ -565,18 +632,18 @@ pub(crate) struct FeaturePreviouslyDeclared<'a> { } #[derive(Diagnostic)] -#[diag(passes_multiple_rustc_main, code = E0137)] +#[diag("multiple functions with a `#[rustc_main]` attribute", code = E0137)] pub(crate) struct MultipleRustcMain { #[primary_span] pub span: Span, - #[label(passes_first)] + #[label("first `#[rustc_main]` function")] pub first: Span, - #[label(passes_additional)] + #[label("additional `#[rustc_main]` function")] pub additional: Span, } #[derive(Diagnostic)] -#[diag(passes_extern_main)] +#[diag("the `main` function cannot be declared in an `extern` block")] pub(crate) struct ExternMain { #[primary_span] pub span: Span, @@ -596,7 +663,11 @@ pub(crate) struct NoMainErr { impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NoMainErr { #[track_caller] fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> { - let mut diag = Diag::new(dcx, level, fluent::passes_no_main_function); + let mut diag = Diag::new( + dcx, + level, + inline_fluent!("`main` function not found in crate `{$crate_name}`"), + ); diag.span(DUMMY_SP); diag.code(E0601); diag.arg("crate_name", self.crate_name); @@ -604,16 +675,23 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NoMainErr { diag.arg("has_filename", self.has_filename); let note = if !self.non_main_fns.is_empty() { for &span in &self.non_main_fns { - diag.span_note(span, fluent::passes_here_is_main); + diag.span_note(span, inline_fluent!("here is a function named `main`")); } - diag.note(fluent::passes_one_or_more_possible_main); - diag.help(fluent::passes_consider_moving_main); + diag.note(inline_fluent!( + "you have one or more functions named `main` not defined at the crate level" + )); + diag.help(inline_fluent!("consider moving the `main` function definitions")); // There were some functions named `main` though. Try to give the user a hint. - fluent::passes_main_must_be_defined_at_crate + inline_fluent!( + "the main function must be defined at the crate level{$has_filename -> + [true] {\" \"}(in `{$filename}`) + *[false] {\"\"} + }" + ) } else if self.has_filename { - fluent::passes_consider_adding_main_to_file + inline_fluent!("consider adding a `main` function to `{$filename}`") } else { - fluent::passes_consider_adding_main_at_crate + inline_fluent!("consider adding a `main` function at the crate level") }; if self.file_empty { diag.note(note); @@ -626,11 +704,14 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NoMainErr { && main_def.opt_fn_def_id().is_none() { // There is something at `crate::main`, but it is not a function definition. - diag.span_label(main_def.span, fluent::passes_non_function_main); + diag.span_label( + main_def.span, + inline_fluent!("non-function item at `crate::main` is found"), + ); } if self.add_teach_note { - diag.note(fluent::passes_teach_note); + diag.note(inline_fluent!("if you don't know the basics of Rust, you can go look to the Rust Book to get started: https://doc.rust-lang.org/book/")); } diag } @@ -658,9 +739,13 @@ impl Diagnostic<'_, G> for DuplicateLangItem { dcx, level, match self.duplicate { - Duplicate::Plain => fluent::passes_duplicate_lang_item, - Duplicate::Crate => fluent::passes_duplicate_lang_item_crate, - Duplicate::CrateDepends => fluent::passes_duplicate_lang_item_crate_depends, + Duplicate::Plain => inline_fluent!("found duplicate lang item `{$lang_item_name}`"), + Duplicate::Crate => inline_fluent!( + "duplicate lang item in crate `{$crate_name}`: `{$lang_item_name}`" + ), + Duplicate::CrateDepends => inline_fluent!( + "duplicate lang item in crate `{$crate_name}` (which `{$dependency_of}` depends on): `{$lang_item_name}`" + ), }, ); diag.code(E0152); @@ -681,24 +766,32 @@ impl Diagnostic<'_, G> for DuplicateLangItem { diag.span(span); } if let Some(span) = self.first_defined_span { - diag.span_note(span, fluent::passes_first_defined_span); + diag.span_note(span, inline_fluent!("the lang item is first defined here")); } else { if self.orig_dependency_of.is_none() { - diag.note(fluent::passes_first_defined_crate); + diag.note(inline_fluent!( + "the lang item is first defined in crate `{$orig_crate_name}`" + )); } else { - diag.note(fluent::passes_first_defined_crate_depends); + diag.note(inline_fluent!("the lang item is first defined in crate `{$orig_crate_name}` (which `{$orig_dependency_of}` depends on)")); } if self.orig_is_local { - diag.note(fluent::passes_first_definition_local); + diag.note(inline_fluent!( + "first definition in the local crate (`{$orig_crate_name}`)" + )); } else { - diag.note(fluent::passes_first_definition_path); + diag.note(inline_fluent!( + "first definition in `{$orig_crate_name}` loaded from {$orig_path}" + )); } if self.is_local { - diag.note(fluent::passes_second_definition_local); + diag.note(inline_fluent!("second definition in the local crate (`{$crate_name}`)")); } else { - diag.note(fluent::passes_second_definition_path); + diag.note(inline_fluent!( + "second definition in `{$crate_name}` loaded from {$path}" + )); } } diag @@ -706,11 +799,22 @@ impl Diagnostic<'_, G> for DuplicateLangItem { } #[derive(Diagnostic)] -#[diag(passes_incorrect_target, code = E0718)] +#[diag("`{$name}` lang item must be applied to a {$kind} with {$at_least -> + [true] at least {$num} + *[false] {$num} + } generic {$num -> + [one] argument + *[other] arguments + }", code = E0718)] pub(crate) struct IncorrectTarget<'a> { #[primary_span] pub span: Span, - #[label] + #[label( + "this {$kind} has {$actual_num} generic {$actual_num -> + [one] argument + *[other] arguments + }" + )] pub generics_span: Span, pub name: &'a str, // cannot be symbol because it renders e.g. `r#fn` instead of `fn` pub kind: &'static str, @@ -720,26 +824,33 @@ pub(crate) struct IncorrectTarget<'a> { } #[derive(Diagnostic)] -#[diag(passes_incorrect_crate_type)] +#[diag("lang items are not allowed in stable dylibs")] pub(crate) struct IncorrectCrateType { #[primary_span] pub span: Span, } #[derive(LintDiagnostic)] -#[diag(passes_useless_assignment)] +#[diag( + "useless assignment of {$is_field_assign -> + [true] field + *[false] variable + } of type `{$ty}` to itself" +)] pub(crate) struct UselessAssignment<'a> { pub is_field_assign: bool, pub ty: Ty<'a>, } #[derive(LintDiagnostic)] -#[diag(passes_inline_ignored_for_exported)] -#[help] +#[diag("`#[inline]` is ignored on externally exported functions")] +#[help( + "externally exported functions are functions with `#[no_mangle]`, `#[export_name]`, or `#[linkage]`" +)] pub(crate) struct InlineIgnoredForExported {} #[derive(Diagnostic)] -#[diag(passes_object_lifetime_err)] +#[diag("{$repr}")] pub(crate) struct ObjectLifetimeErr { #[primary_span] pub span: Span, @@ -748,38 +859,38 @@ pub(crate) struct ObjectLifetimeErr { #[derive(Diagnostic)] pub(crate) enum AttrApplication { - #[diag(passes_attr_application_enum, code = E0517)] + #[diag("attribute should be applied to an enum", code = E0517)] Enum { #[primary_span] hint_span: Span, - #[label] + #[label("not an enum")] span: Span, }, - #[diag(passes_attr_application_struct, code = E0517)] + #[diag("attribute should be applied to a struct", code = E0517)] Struct { #[primary_span] hint_span: Span, - #[label] + #[label("not a struct")] span: Span, }, - #[diag(passes_attr_application_struct_union, code = E0517)] + #[diag("attribute should be applied to a struct or union", code = E0517)] StructUnion { #[primary_span] hint_span: Span, - #[label] + #[label("not a struct or union")] span: Span, }, - #[diag(passes_attr_application_struct_enum_union, code = E0517)] + #[diag("attribute should be applied to a struct, enum, or union", code = E0517)] StructEnumUnion { #[primary_span] hint_span: Span, - #[label] + #[label("not a struct, enum, or union")] span: Span, }, } #[derive(Diagnostic)] -#[diag(passes_transparent_incompatible, code = E0692)] +#[diag("transparent {$target} cannot have other repr hints", code = E0692)] pub(crate) struct TransparentIncompatible { #[primary_span] pub hint_spans: Vec, @@ -787,45 +898,45 @@ pub(crate) struct TransparentIncompatible { } #[derive(Diagnostic)] -#[diag(passes_deprecated_attribute, code = E0549)] +#[diag("deprecated attribute must be paired with either stable or unstable attribute", code = E0549)] pub(crate) struct DeprecatedAttribute { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_useless_stability)] +#[diag("this stability annotation is useless")] pub(crate) struct UselessStability { #[primary_span] - #[label] + #[label("useless stability annotation")] pub span: Span, - #[label(passes_item)] + #[label("the stability attribute annotates this item")] pub item_sp: Span, } #[derive(Diagnostic)] -#[diag(passes_cannot_stabilize_deprecated)] +#[diag("an API can't be stabilized after it is deprecated")] pub(crate) struct CannotStabilizeDeprecated { #[primary_span] - #[label] + #[label("invalid version")] pub span: Span, - #[label(passes_item)] + #[label("the stability attribute annotates this item")] pub item_sp: Span, } #[derive(Diagnostic)] -#[diag(passes_unstable_attr_for_already_stable_feature)] +#[diag("can't mark as unstable using an already stable feature")] pub(crate) struct UnstableAttrForAlreadyStableFeature { #[primary_span] - #[label] - #[help] + #[label("this feature is already stable")] + #[help("consider removing the attribute")] pub attr_span: Span, - #[label(passes_item)] + #[label("the stability attribute annotates this item")] pub item_span: Span, } #[derive(Diagnostic)] -#[diag(passes_missing_stability_attr)] +#[diag("{$descr} has missing stability attribute")] pub(crate) struct MissingStabilityAttr<'a> { #[primary_span] pub span: Span, @@ -833,7 +944,7 @@ pub(crate) struct MissingStabilityAttr<'a> { } #[derive(Diagnostic)] -#[diag(passes_missing_const_stab_attr)] +#[diag("{$descr} has missing const stability attribute")] pub(crate) struct MissingConstStabAttr<'a> { #[primary_span] pub span: Span, @@ -841,15 +952,15 @@ pub(crate) struct MissingConstStabAttr<'a> { } #[derive(Diagnostic)] -#[diag(passes_trait_impl_const_stable)] -#[note] +#[diag("trait implementations cannot be const stable yet")] +#[note("see issue #143874 for more information")] pub(crate) struct TraitImplConstStable { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_trait_impl_const_stability_mismatch)] +#[diag("const stability on the impl does not match the const stability on the trait")] pub(crate) struct TraitImplConstStabilityMismatch { #[primary_span] pub span: Span, @@ -861,12 +972,12 @@ pub(crate) struct TraitImplConstStabilityMismatch { #[derive(Subdiagnostic)] pub(crate) enum TraitConstStability { - #[note(passes_trait_impl_const_stability_mismatch_trait_stable)] + #[note("...but the trait is stable")] Stable { #[primary_span] span: Span, }, - #[note(passes_trait_impl_const_stability_mismatch_trait_unstable)] + #[note("...but the trait is unstable")] Unstable { #[primary_span] span: Span, @@ -875,12 +986,12 @@ pub(crate) enum TraitConstStability { #[derive(Subdiagnostic)] pub(crate) enum ImplConstStability { - #[note(passes_trait_impl_const_stability_mismatch_impl_stable)] + #[note("this impl is (implicitly) stable...")] Stable { #[primary_span] span: Span, }, - #[note(passes_trait_impl_const_stability_mismatch_impl_unstable)] + #[note("this impl is unstable...")] Unstable { #[primary_span] span: Span, @@ -888,7 +999,7 @@ pub(crate) enum ImplConstStability { } #[derive(Diagnostic)] -#[diag(passes_unknown_feature, code = E0635)] +#[diag("unknown feature `{$feature}`", code = E0635)] pub(crate) struct UnknownFeature { #[primary_span] pub span: Span, @@ -899,7 +1010,7 @@ pub(crate) struct UnknownFeature { #[derive(Subdiagnostic)] #[suggestion( - passes_misspelled_feature, + "there is a feature with a similar name: `{$actual_name}`", style = "verbose", code = "{actual_name}", applicability = "maybe-incorrect" @@ -911,7 +1022,7 @@ pub(crate) struct MisspelledFeature { } #[derive(Diagnostic)] -#[diag(passes_unknown_feature_alias, code = E0635)] +#[diag("feature `{$alias}` has been renamed to `{$feature}`", code = E0635)] pub(crate) struct RenamedFeature { #[primary_span] pub span: Span, @@ -920,7 +1031,7 @@ pub(crate) struct RenamedFeature { } #[derive(Diagnostic)] -#[diag(passes_implied_feature_not_exist)] +#[diag("feature `{$implied_by}` implying `{$feature}` does not exist")] pub(crate) struct ImpliedFeatureNotExist { #[primary_span] pub span: Span, @@ -929,7 +1040,7 @@ pub(crate) struct ImpliedFeatureNotExist { } #[derive(Diagnostic)] -#[diag(passes_duplicate_feature_err, code = E0636)] +#[diag("the feature `{$feature}` has already been enabled", code = E0636)] pub(crate) struct DuplicateFeatureErr { #[primary_span] pub span: Span, @@ -937,25 +1048,37 @@ pub(crate) struct DuplicateFeatureErr { } #[derive(Diagnostic)] -#[diag(passes_missing_const_err)] +#[diag( + "attributes `#[rustc_const_unstable]`, `#[rustc_const_stable]` and `#[rustc_const_stable_indirect]` require the function or method to be `const`" +)] pub(crate) struct MissingConstErr { #[primary_span] - #[help] + #[help("make the function or method const")] pub fn_sig_span: Span, } #[derive(Diagnostic)] -#[diag(passes_const_stable_not_stable)] +#[diag( + "attribute `#[rustc_const_stable]` can only be applied to functions that are declared `#[stable]`" +)] pub(crate) struct ConstStableNotStable { #[primary_span] pub fn_sig_span: Span, - #[label] + #[label("attribute specified here")] pub const_span: Span, } #[derive(LintDiagnostic)] pub(crate) enum MultipleDeadCodes<'tcx> { - #[diag(passes_dead_codes)] + #[diag( + "{ $multiple -> + *[true] multiple {$descr}s are + [false] { $num -> + [one] {$descr} {$name_list} is + *[other] {$descr}s {$name_list} are + } + } never {$participle}" + )] DeadCodes { multiple: bool, num: usize, @@ -970,7 +1093,15 @@ pub(crate) enum MultipleDeadCodes<'tcx> { #[subdiagnostic] ignored_derived_impls: Option, }, - #[diag(passes_dead_codes)] + #[diag( + "{ $multiple -> + *[true] multiple {$descr}s are + [false] { $num -> + [one] {$descr} {$name_list} is + *[other] {$descr}s {$name_list} are + } + } never {$participle}" + )] UnusedTupleStructFields { multiple: bool, num: usize, @@ -987,7 +1118,9 @@ pub(crate) enum MultipleDeadCodes<'tcx> { } #[derive(Subdiagnostic)] -#[note(passes_enum_variant_same_name)] +#[note( + "it is impossible to refer to the {$dead_descr} `{$dead_name}` because it is shadowed by this enum variant with the same name" +)] pub(crate) struct EnumVariantSameName<'tcx> { #[primary_span] pub variant_span: Span, @@ -996,7 +1129,12 @@ pub(crate) struct EnumVariantSameName<'tcx> { } #[derive(Subdiagnostic)] -#[label(passes_parent_info)] +#[label( + "{$num -> + [one] {$descr} + *[other] {$descr}s + } in this {$parent_descr}" +)] pub(crate) struct ParentInfo<'tcx> { pub num: usize, pub descr: &'tcx str, @@ -1006,7 +1144,15 @@ pub(crate) struct ParentInfo<'tcx> { } #[derive(Subdiagnostic)] -#[note(passes_ignored_derived_impls)] +#[note( + "`{$name}` has {$trait_list_len -> + [one] a derived impl + *[other] derived impls + } for the {$trait_list_len -> + [one] trait {$trait_list}, but this is + *[other] traits {$trait_list}, but these are + } intentionally ignored during dead code analysis" +)] pub(crate) struct IgnoredDerivedImpls { pub name: Symbol, pub trait_list: DiagSymbolList, @@ -1016,7 +1162,13 @@ pub(crate) struct IgnoredDerivedImpls { #[derive(Subdiagnostic)] pub(crate) enum ChangeFields { #[multipart_suggestion( - passes_change_fields_to_be_of_unit_type, + "consider changing the { $num -> + [one] field + *[other] fields + } to be of unit type to suppress this warning while preserving the field numbering, or remove the { $num -> + [one] field + *[other] fields + }", applicability = "has-placeholders" )] ChangeToUnitTypeOrRemove { @@ -1024,12 +1176,20 @@ pub(crate) enum ChangeFields { #[suggestion_part(code = "()")] spans: Vec, }, - #[help(passes_remove_fields)] + #[help( + "consider removing { $num -> + [one] this + *[other] these + } { $num -> + [one] field + *[other] fields + }" + )] Remove { num: usize }, } #[derive(Diagnostic)] -#[diag(passes_proc_macro_bad_sig)] +#[diag("{$kind} has incorrect signature")] pub(crate) struct ProcMacroBadSig { #[primary_span] pub span: Span, @@ -1037,18 +1197,30 @@ pub(crate) struct ProcMacroBadSig { } #[derive(LintDiagnostic)] -#[diag(passes_unnecessary_stable_feature)] +#[diag( + "the feature `{$feature}` has been stable since {$since} and no longer requires an attribute to enable" +)] pub(crate) struct UnnecessaryStableFeature { pub feature: Symbol, pub since: Symbol, } #[derive(LintDiagnostic)] -#[diag(passes_unnecessary_partial_stable_feature)] +#[diag( + "the feature `{$feature}` has been partially stabilized since {$since} and is succeeded by the feature `{$implies}`" +)] pub(crate) struct UnnecessaryPartialStableFeature { - #[suggestion(code = "{implies}", applicability = "maybe-incorrect")] + #[suggestion( + "if you are using features which are still unstable, change to using `{$implies}`", + code = "{implies}", + applicability = "maybe-incorrect" + )] pub span: Span, - #[suggestion(passes_suggestion_remove, code = "", applicability = "maybe-incorrect")] + #[suggestion( + "if you are using features which are now stable, remove this line", + code = "", + applicability = "maybe-incorrect" + )] pub line: Span, pub feature: Symbol, pub since: Symbol, @@ -1056,38 +1228,36 @@ pub(crate) struct UnnecessaryPartialStableFeature { } #[derive(LintDiagnostic)] -#[diag(passes_ineffective_unstable_impl)] -#[note] +#[diag("an `#[unstable]` annotation here has no effect")] +#[note("see issue #55436 for more information")] pub(crate) struct IneffectiveUnstableImpl; -/// "sanitize attribute not allowed here" #[derive(Diagnostic)] -#[diag(passes_sanitize_attribute_not_allowed)] +#[diag("sanitize attribute not allowed here")] pub(crate) struct SanitizeAttributeNotAllowed { #[primary_span] pub attr_span: Span, - /// "not a function, impl block, or module" - #[label(passes_not_fn_impl_mod)] + #[label("not a function, impl block, or module")] pub not_fn_impl_mod: Option, - /// "function has no body" - #[label(passes_no_body)] + #[label("function has no body")] pub no_body: Option, - /// "sanitize attribute can be applied to a function (with body), impl block, or module" - #[help] + #[help("sanitize attribute can be applied to a function (with body), impl block, or module")] pub help: (), } // FIXME(jdonszelmann): move back to rustc_attr #[derive(Diagnostic)] -#[diag(passes_rustc_const_stable_indirect_pairing)] +#[diag( + "`const_stable_indirect` attribute does not make sense on `rustc_const_stable` function, its behavior is already implied" +)] pub(crate) struct RustcConstStableIndirectPairing { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_unsupported_attributes_in_where)] -#[help] +#[diag("most attributes are not supported in `where` clauses")] +#[help("only `#[cfg]` and `#[cfg_attr]` are supported")] pub(crate) struct UnsupportedAttributesInWhere { #[primary_span] pub span: MultiSpan, @@ -1095,100 +1265,100 @@ pub(crate) struct UnsupportedAttributesInWhere { #[derive(Diagnostic)] pub(crate) enum UnexportableItem<'a> { - #[diag(passes_unexportable_item)] + #[diag("{$descr}'s are not exportable")] Item { #[primary_span] span: Span, descr: &'a str, }, - #[diag(passes_unexportable_generic_fn)] + #[diag("generic functions are not exportable")] GenericFn(#[primary_span] Span), - #[diag(passes_unexportable_fn_abi)] + #[diag("only functions with \"C\" ABI are exportable")] FnAbi(#[primary_span] Span), - #[diag(passes_unexportable_type_repr)] + #[diag("types with unstable layout are not exportable")] TypeRepr(#[primary_span] Span), - #[diag(passes_unexportable_type_in_interface)] + #[diag("{$desc} with `#[export_stable]` attribute uses type `{$ty}`, which is not exportable")] TypeInInterface { #[primary_span] span: Span, desc: &'a str, ty: &'a str, - #[label] + #[label("not exportable")] ty_span: Span, }, - #[diag(passes_unexportable_priv_item)] + #[diag("private items are not exportable")] PrivItem { #[primary_span] span: Span, - #[note] + #[note("is only usable at visibility `{$vis_descr}`")] vis_note: Span, vis_descr: &'a str, }, - #[diag(passes_unexportable_adt_with_private_fields)] + #[diag("ADT types with private fields are not exportable")] AdtWithPrivFields { #[primary_span] span: Span, - #[note] + #[note("`{$field_name}` is private")] vis_note: Span, field_name: &'a str, }, } #[derive(Diagnostic)] -#[diag(passes_repr_align_should_be_align)] +#[diag("`#[repr(align(...))]` is not supported on {$item}")] pub(crate) struct ReprAlignShouldBeAlign { #[primary_span] - #[help] + #[help("use `#[rustc_align(...)]` instead")] pub span: Span, pub item: &'static str, } #[derive(Diagnostic)] -#[diag(passes_repr_align_should_be_align_static)] +#[diag("`#[repr(align(...))]` is not supported on {$item}")] pub(crate) struct ReprAlignShouldBeAlignStatic { #[primary_span] - #[help] + #[help("use `#[rustc_align_static(...)]` instead")] pub span: Span, pub item: &'static str, } #[derive(Diagnostic)] -#[diag(passes_custom_mir_phase_requires_dialect)] +#[diag("`dialect` key required")] pub(crate) struct CustomMirPhaseRequiresDialect { #[primary_span] pub attr_span: Span, - #[label] + #[label("`phase` argument requires a `dialect` argument")] pub phase_span: Span, } #[derive(Diagnostic)] -#[diag(passes_custom_mir_incompatible_dialect_and_phase)] +#[diag("the {$dialect} dialect is not compatible with the {$phase} phase")] pub(crate) struct CustomMirIncompatibleDialectAndPhase { pub dialect: MirDialect, pub phase: MirPhase, #[primary_span] pub attr_span: Span, - #[label] + #[label("this dialect...")] pub dialect_span: Span, - #[label] + #[label("... is not compatible with this phase")] pub phase_span: Span, } #[derive(Diagnostic)] -#[diag(passes_eii_impl_not_function)] +#[diag("`eii_macro_for` is only valid on functions")] pub(crate) struct EiiImplNotFunction { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_eii_impl_requires_unsafe)] +#[diag("`#[{$name}]` is unsafe to implement")] pub(crate) struct EiiImplRequiresUnsafe { #[primary_span] pub span: Span, @@ -1198,10 +1368,7 @@ pub(crate) struct EiiImplRequiresUnsafe { } #[derive(Subdiagnostic)] -#[multipart_suggestion( - passes_eii_impl_requires_unsafe_suggestion, - applicability = "machine-applicable" -)] +#[multipart_suggestion("wrap the attribute in `unsafe(...)`", applicability = "machine-applicable")] pub(crate) struct EiiImplRequiresUnsafeSuggestion { #[suggestion_part(code = "unsafe(")] pub left: Span, @@ -1210,64 +1377,71 @@ pub(crate) struct EiiImplRequiresUnsafeSuggestion { } #[derive(Diagnostic)] -#[diag(passes_eii_fn_with_track_caller)] +#[diag("`#[{$name}]` is not allowed to have `#[track_caller]`")] pub(crate) struct EiiWithTrackCaller { #[primary_span] pub attr_span: Span, pub name: Symbol, - #[label] + #[label("`#[{$name}]` is not allowed to have `#[track_caller]`")] pub sig_span: Span, } #[derive(Diagnostic)] -#[diag(passes_eii_without_impl)] +#[diag("`#[{$name}]` required, but not found")] pub(crate) struct EiiWithoutImpl { #[primary_span] - #[label] + #[label("expected because `#[{$name}]` was declared here in crate `{$decl_crate_name}`")] pub span: Span, pub name: Symbol, pub current_crate_name: Symbol, pub decl_crate_name: Symbol, - #[help] + #[help( + "expected at least one implementation in crate `{$current_crate_name}` or any of its dependencies" + )] pub help: (), } #[derive(Diagnostic)] -#[diag(passes_duplicate_eii_impls)] +#[diag("multiple implementations of `#[{$name}]`")] pub(crate) struct DuplicateEiiImpls { pub name: Symbol, #[primary_span] - #[label(passes_first)] + #[label("first implemented here in crate `{$first_crate}`")] pub first_span: Span, pub first_crate: Symbol, - #[label(passes_second)] + #[label("also implemented here in crate `{$second_crate}`")] pub second_span: Span, pub second_crate: Symbol, - #[note] + #[note("in addition to these two, { $num_additional_crates -> + [one] another implementation was found in crate {$additional_crate_names} + *[other] more implementations were also found in the following crates: {$additional_crate_names} + }")] pub additional_crates: Option<()>, pub num_additional_crates: usize, pub additional_crate_names: String, - #[help] + #[help( + "an \"externally implementable item\" can only have a single implementation in the final artifact. When multiple implementations are found, also in different crates, they conflict" + )] pub help: (), } #[derive(Diagnostic)] -#[diag(passes_function_not_have_default_implementation)] +#[diag("function doesn't have a default implementation")] pub(crate) struct FunctionNotHaveDefaultImplementation { #[primary_span] pub span: Span, - #[note] + #[note("required by this annotation")] pub note_span: Span, } #[derive(Diagnostic)] -#[diag(passes_must_implement_not_function)] +#[diag("not a function")] pub(crate) struct MustImplementNotFunction { #[primary_span] pub span: Span, @@ -1278,26 +1452,26 @@ pub(crate) struct MustImplementNotFunction { } #[derive(Subdiagnostic)] -#[note(passes_must_implement_not_function_span_note)] +#[note("required by this annotation")] pub(crate) struct MustImplementNotFunctionSpanNote { #[primary_span] pub span: Span, } #[derive(Subdiagnostic)] -#[note(passes_must_implement_not_function_note)] +#[note("all `#[rustc_must_implement_one_of]` arguments must be associated function names")] pub(crate) struct MustImplementNotFunctionNote {} #[derive(Diagnostic)] -#[diag(passes_function_not_found_in_trait)] +#[diag("function not found in this trait")] pub(crate) struct FunctionNotFoundInTrait { #[primary_span] pub span: Span, } #[derive(Diagnostic)] -#[diag(passes_functions_names_duplicated)] -#[note] +#[diag("functions names are duplicated")] +#[note("all `#[rustc_must_implement_one_of]` arguments must be unique")] pub(crate) struct FunctionNamesDuplicated { #[primary_span] pub spans: Vec, diff --git a/compiler/rustc_passes/src/lib.rs b/compiler/rustc_passes/src/lib.rs index d371589cba6ca..ef6a8e80c72f2 100644 --- a/compiler/rustc_passes/src/lib.rs +++ b/compiler/rustc_passes/src/lib.rs @@ -30,8 +30,6 @@ pub mod stability; mod upvars; mod weak_lang_items; -rustc_fluent_macro::fluent_messages! { "../messages.ftl" } - pub fn provide(providers: &mut Providers) { check_attr::provide(providers); dead::provide(providers); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1c9154238657d..753fba3ed4825 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -334,7 +334,7 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg<'tcx>) -> ConstantKind } hir::ConstArgKind::Anon(anon) => ConstantKind::Anonymous { body: anon.body }, hir::ConstArgKind::Infer(..) | hir::ConstArgKind::Error(..) => ConstantKind::Infer, - hir::ConstArgKind::Literal(..) => { + hir::ConstArgKind::Literal { .. } => { ConstantKind::Path { path: "/* LITERAL */".to_string().into() } } } @@ -1829,7 +1829,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T | hir::ConstArgKind::TupleCall(..) | hir::ConstArgKind::Tup(..) | hir::ConstArgKind::Array(..) - | hir::ConstArgKind::Literal(..) => { + | hir::ConstArgKind::Literal { .. } => { let ct = lower_const_arg_for_rustdoc(cx.tcx, const_arg, cx.tcx.types.usize); print_const(cx, ct) } diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs index e6fadc783621d..d5191794b6b06 100644 --- a/src/tools/clippy/clippy_lints/src/utils/author.rs +++ b/src/tools/clippy/clippy_lints/src/utils/author.rs @@ -325,7 +325,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> { ConstArgKind::Infer(..) => chain!(self, "let ConstArgKind::Infer(..) = {const_arg}.kind"), ConstArgKind::Error(..) => chain!(self, "let ConstArgKind::Error(..) = {const_arg}.kind"), ConstArgKind::Tup(..) => chain!(self, "let ConstArgKind::Tup(..) = {const_arg}.kind"), - ConstArgKind::Literal(..) => chain!(self, "let ConstArgKind::Literal(..) = {const_arg}.kind"), + ConstArgKind::Literal { .. } => chain!(self, "let ConstArgKind::Literal {{ .. }} = {const_arg}.kind"), } } diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index e2ada37d53b39..8177a5806d787 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -1142,7 +1142,7 @@ pub fn const_item_rhs_to_expr<'tcx>(tcx: TyCtxt<'tcx>, ct_rhs: ConstItemRhs<'tcx ConstArgKind::Anon(anon) => Some(tcx.hir_body(anon.body).value), ConstArgKind::Struct(..) | ConstArgKind::Tup(..) - | ConstArgKind::Literal(..) + | ConstArgKind::Literal { .. } | ConstArgKind::TupleCall(..) | ConstArgKind::Array(..) | ConstArgKind::Path(_) diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index b9f104a79a27c..abc6885bef2d1 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -686,7 +686,16 @@ impl HirEqInterExpr<'_, '_, '_> { .zip(*args_b) .all(|(arg_a, arg_b)| self.eq_const_arg(arg_a, arg_b)) }, - (ConstArgKind::Literal(kind_l), ConstArgKind::Literal(kind_r)) => kind_l == kind_r, + ( + ConstArgKind::Literal { + lit: kind_l, + negated: negated_l, + }, + ConstArgKind::Literal { + lit: kind_r, + negated: negated_r, + }, + ) => kind_l == kind_r && negated_l == negated_r, (ConstArgKind::Array(l_arr), ConstArgKind::Array(r_arr)) => { l_arr.elems.len() == r_arr.elems.len() && l_arr @@ -703,7 +712,7 @@ impl HirEqInterExpr<'_, '_, '_> { | ConstArgKind::TupleCall(..) | ConstArgKind::Infer(..) | ConstArgKind::Struct(..) - | ConstArgKind::Literal(..) + | ConstArgKind::Literal { .. } | ConstArgKind::Array(..) | ConstArgKind::Error(..), _, @@ -1599,7 +1608,10 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } }, ConstArgKind::Infer(..) | ConstArgKind::Error(..) => {}, - ConstArgKind::Literal(lit) => lit.hash(&mut self.s), + ConstArgKind::Literal { lit, negated } => { + lit.hash(&mut self.s); + negated.hash(&mut self.s); + }, } } diff --git a/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs b/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs new file mode 100644 index 0000000000000..6ec1071461c54 --- /dev/null +++ b/tests/ui/const-generics/generic_const_exprs/auxiliary/non_local_type_const.rs @@ -0,0 +1,5 @@ +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +#[type_const] +pub const NON_LOCAL_CONST: char = 'a'; diff --git a/tests/ui/const-generics/generic_const_exprs/non-local-const.rs b/tests/ui/const-generics/generic_const_exprs/non-local-const.rs index 0a30cc385ac43..d0efdb2c20171 100644 --- a/tests/ui/const-generics/generic_const_exprs/non-local-const.rs +++ b/tests/ui/const-generics/generic_const_exprs/non-local-const.rs @@ -1,10 +1,12 @@ // regression test for #133808. +//@ aux-build:non_local_type_const.rs #![feature(generic_const_exprs)] #![feature(min_generic_const_args)] #![allow(incomplete_features)] #![crate_type = "lib"] +extern crate non_local_type_const; pub trait Foo {} -impl Foo for [u8; std::path::MAIN_SEPARATOR] {} -//~^ ERROR the constant `MAIN_SEPARATOR` is not of type `usize` +impl Foo for [u8; non_local_type_const::NON_LOCAL_CONST] {} +//~^ ERROR the constant `'a'` is not of type `usize` diff --git a/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr b/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr index d8df3269a19e9..3d1ec60eb908d 100644 --- a/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr +++ b/tests/ui/const-generics/generic_const_exprs/non-local-const.stderr @@ -1,10 +1,10 @@ -error: the constant `MAIN_SEPARATOR` is not of type `usize` - --> $DIR/non-local-const.rs:9:14 +error: the constant `'a'` is not of type `usize` + --> $DIR/non-local-const.rs:11:14 | -LL | impl Foo for [u8; std::path::MAIN_SEPARATOR] {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `char` +LL | impl Foo for [u8; non_local_type_const::NON_LOCAL_CONST] {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `char` | - = note: the length of array `[u8; MAIN_SEPARATOR]` must be type `usize` + = note: the length of array `[u8; 'a']` must be type `usize` error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr index 7872e09676268..e06850747ff3a 100644 --- a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr +++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr @@ -1,18 +1,26 @@ -error: use of trait associated const without `#[type_const]` +error: use of `const` in the type system without `#[type_const]` --> $DIR/assoc-const-without-type_const.rs:8:35 | LL | fn mk_array(_x: T) -> [(); T::SIZE] { | ^^^^^^^ | - = note: the declaration in the trait must be marked with `#[type_const]` +help: add `#[type_const]` attribute to `Tr::SIZE` + | +LL + #[type_const] +LL | const SIZE: usize; + | -error: use of trait associated const without `#[type_const]` +error: use of `const` in the type system without `#[type_const]` --> $DIR/assoc-const-without-type_const.rs:10:10 | LL | [(); T::SIZE] | ^^^^^^^ | - = note: the declaration in the trait must be marked with `#[type_const]` +help: add `#[type_const]` attribute to `Tr::SIZE` + | +LL + #[type_const] +LL | const SIZE: usize; + | error: aborting due to 2 previous errors diff --git a/tests/ui/const-generics/mgca/auxiliary/non_local_const.rs b/tests/ui/const-generics/mgca/auxiliary/non_local_const.rs new file mode 100644 index 0000000000000..19091e4780fef --- /dev/null +++ b/tests/ui/const-generics/mgca/auxiliary/non_local_const.rs @@ -0,0 +1 @@ +pub const N: usize = 2; diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs index 68aa30bd65bbe..efab014894044 100644 --- a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.rs @@ -3,6 +3,7 @@ #![expect(incomplete_features)] #![feature(min_generic_const_args)] +#[type_const] const C: usize = 0; pub struct A {} impl A { diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr index 3d74d1db206e1..6b2b871ba4b98 100644 --- a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr @@ -1,11 +1,11 @@ error[E0107]: missing generics for struct `A` - --> $DIR/const-arg-coherence-conflicting-methods.rs:12:6 + --> $DIR/const-arg-coherence-conflicting-methods.rs:13:6 | LL | impl A { | ^ expected 1 generic argument | note: struct defined here, with 1 generic parameter: `M` - --> $DIR/const-arg-coherence-conflicting-methods.rs:7:12 + --> $DIR/const-arg-coherence-conflicting-methods.rs:8:12 | LL | pub struct A {} | ^ -------------- @@ -15,7 +15,7 @@ LL | impl A { | +++ error[E0592]: duplicate definitions with name `fun1` - --> $DIR/const-arg-coherence-conflicting-methods.rs:9:5 + --> $DIR/const-arg-coherence-conflicting-methods.rs:10:5 | LL | fn fun1() {} | ^^^^^^^^^ duplicate definitions for `fun1` diff --git a/tests/ui/const-generics/mgca/negated-literal.rs b/tests/ui/const-generics/mgca/negated-literal.rs new file mode 100644 index 0000000000000..a7651822b0a83 --- /dev/null +++ b/tests/ui/const-generics/mgca/negated-literal.rs @@ -0,0 +1,17 @@ +//@ check-pass + +#![feature(adt_const_params, min_generic_const_args)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Eq, PartialEq, ConstParamTy)] +struct Foo { + field: isize +} + +fn foo() {} + +fn main() { + foo::<{ Foo { field: -1 } }>(); +} diff --git a/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs b/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs new file mode 100644 index 0000000000000..e98cbdf8e6175 --- /dev/null +++ b/tests/ui/const-generics/mgca/non-local-const-without-type_const.rs @@ -0,0 +1,9 @@ +// Just a test of the error message (it's different for non-local consts) +//@ aux-build:non_local_const.rs +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] +extern crate non_local_const; +fn main() { + let x = [(); non_local_const::N]; + //~^ ERROR use of `const` in the type system without `#[type_const]` +} diff --git a/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr b/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr new file mode 100644 index 0000000000000..671dfa5fbb9eb --- /dev/null +++ b/tests/ui/const-generics/mgca/non-local-const-without-type_const.stderr @@ -0,0 +1,10 @@ +error: use of `const` in the type system without `#[type_const]` + --> $DIR/non-local-const-without-type_const.rs:7:18 + | +LL | let x = [(); non_local_const::N]; + | ^^^^^^^^^^^^^^^^^^ + | + = note: only consts marked with `#[type_const]` may be used in types + +error: aborting due to 1 previous error + diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs index 84ded05fdd0e3..ebbe097c226e8 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.rs @@ -12,6 +12,7 @@ enum MyEnum { Unit, } +#[type_const] const CONST_ITEM: u32 = 42; fn accepts_point() {} diff --git a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr index cc6144b9c88af..dc6a700a8e126 100644 --- a/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr +++ b/tests/ui/const-generics/mgca/tuple_ctor_erroneous.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find function, tuple struct or tuple variant `UnresolvedIdent` in this scope - --> $DIR/tuple_ctor_erroneous.rs:29:23 + --> $DIR/tuple_ctor_erroneous.rs:30:23 | LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); | ^^^^^^^^^^^^^^^ not found in this scope @@ -10,55 +10,55 @@ LL | fn test_errors() { | +++++++++++++++++++++++++++++++++++ error: tuple constructor has 2 arguments but 1 were provided - --> $DIR/tuple_ctor_erroneous.rs:23:23 + --> $DIR/tuple_ctor_erroneous.rs:24:23 | LL | accepts_point::<{ Point(N) }>(); | ^^^^^^^^ error: tuple constructor has 2 arguments but 3 were provided - --> $DIR/tuple_ctor_erroneous.rs:26:23 + --> $DIR/tuple_ctor_erroneous.rs:27:23 | LL | accepts_point::<{ Point(N, N, N) }>(); | ^^^^^^^^^^^^^^ error: tuple constructor with invalid base path - --> $DIR/tuple_ctor_erroneous.rs:29:23 + --> $DIR/tuple_ctor_erroneous.rs:30:23 | LL | accepts_point::<{ UnresolvedIdent(N, N) }>(); | ^^^^^^^^^^^^^^^^^^^^^ error: tuple constructor with invalid base path - --> $DIR/tuple_ctor_erroneous.rs:33:23 + --> $DIR/tuple_ctor_erroneous.rs:34:23 | LL | accepts_point::<{ non_ctor(N, N) }>(); | ^^^^^^^^^^^^^^ error: tuple constructor with invalid base path - --> $DIR/tuple_ctor_erroneous.rs:36:23 + --> $DIR/tuple_ctor_erroneous.rs:37:23 | LL | accepts_point::<{ CONST_ITEM(N, N) }>(); | ^^^^^^^^^^^^^^^^ error: the constant `Point` is not of type `Point` - --> $DIR/tuple_ctor_erroneous.rs:39:23 + --> $DIR/tuple_ctor_erroneous.rs:40:23 | LL | accepts_point::<{ Point }>(); | ^^^^^ expected `Point`, found struct constructor | note: required by a const generic parameter in `accepts_point` - --> $DIR/tuple_ctor_erroneous.rs:17:18 + --> $DIR/tuple_ctor_erroneous.rs:18:18 | LL | fn accepts_point() {} | ^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_point` error: the constant `MyEnum::::Variant` is not of type `MyEnum` - --> $DIR/tuple_ctor_erroneous.rs:42:22 + --> $DIR/tuple_ctor_erroneous.rs:43:22 | LL | accepts_enum::<{ MyEnum::Variant:: }>(); | ^^^^^^^^^^^^^^^^^^^^^^ expected `MyEnum`, found enum constructor | note: required by a const generic parameter in `accepts_enum` - --> $DIR/tuple_ctor_erroneous.rs:18:17 + --> $DIR/tuple_ctor_erroneous.rs:19:17 | LL | fn accepts_enum>() {} | ^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_enum` diff --git a/tests/ui/const-generics/mgca/unmarked-free-const.rs b/tests/ui/const-generics/mgca/unmarked-free-const.rs new file mode 100644 index 0000000000000..a517231facb72 --- /dev/null +++ b/tests/ui/const-generics/mgca/unmarked-free-const.rs @@ -0,0 +1,11 @@ +// regression test, used to ICE + +#![feature(min_generic_const_args)] +#![allow(incomplete_features)] + +const N: usize = 4; + +fn main() { + let x = [(); N]; + //~^ ERROR use of `const` in the type system without `#[type_const]` +} diff --git a/tests/ui/const-generics/mgca/unmarked-free-const.stderr b/tests/ui/const-generics/mgca/unmarked-free-const.stderr new file mode 100644 index 0000000000000..052ae39fdf67b --- /dev/null +++ b/tests/ui/const-generics/mgca/unmarked-free-const.stderr @@ -0,0 +1,14 @@ +error: use of `const` in the type system without `#[type_const]` + --> $DIR/unmarked-free-const.rs:9:18 + | +LL | let x = [(); N]; + | ^ + | +help: add `#[type_const]` attribute to `N` + | +LL + #[type_const] +LL | const N: usize = 4; + | + +error: aborting due to 1 previous error +