Auto merge of #152239 - JonathanBrouwer:rollup-2BolGX5, r=JonathanBrouwer

Rollup of 3 pull requests

Successful merges:

 - rust-lang/rust#152129 (MGCA: require #[type_const] on free consts too)
 - rust-lang/rust#152139 (mGCA: Support directly represented negated literals)
 - rust-lang/rust#152189 (Convert to inline diagnostics in `rustc_passes`)
This commit is contained in:
bors 2026-02-06 18:42:38 +00:00
commit efc9e1b50c
32 changed files with 632 additions and 912 deletions

View file

@ -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",

View file

@ -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,
}
}

View file

@ -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" }

View file

@ -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
];

View file

@ -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.

View file

@ -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)
}
}

View file

@ -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<Const<'tcx>, 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 {

View file

@ -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 })
}
}
}

View file

@ -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,
},

View file

@ -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" }

View file

@ -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} <https://github.com/rust-lang/rust/issues/{$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 <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#inline-and-no_inline> 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 <https://doc.rust-lang.org/unstable-book/language-features/doc-masked.html> 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 <https://github.com/rust-lang/rust/issues/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 <https://github.com/rust-lang/rust/issues/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

View file

@ -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();
}

File diff suppressed because it is too large Load diff

View file

@ -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);

View file

@ -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)
}

View file

@ -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"),
}
}

View file

@ -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(_)

View file

@ -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);
},
}
}

View file

@ -0,0 +1,5 @@
#![feature(min_generic_const_args)]
#![allow(incomplete_features)]
#[type_const]
pub const NON_LOCAL_CONST: char = 'a';

View file

@ -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`

View file

@ -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

View file

@ -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<T: Tr>(_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

View file

@ -0,0 +1 @@
pub const N: usize = 2;

View file

@ -3,6 +3,7 @@
#![expect(incomplete_features)]
#![feature(min_generic_const_args)]
#[type_const]
const C: usize = 0;
pub struct A<const M: usize> {}
impl A<C> {

View file

@ -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<const M: usize> {}
| ^ --------------
@ -15,7 +15,7 @@ LL | impl A<M> {
| +++
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`

View file

@ -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<const F: Foo>() {}
fn main() {
foo::<{ Foo { field: -1 } }>();
}

View file

@ -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]`
}

View file

@ -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

View file

@ -12,6 +12,7 @@ enum MyEnum<T> {
Unit,
}
#[type_const]
const CONST_ITEM: u32 = 42;
fn accepts_point<const P: Point>() {}

View file

@ -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<const N: usize, const UnresolvedIdent: /* Type */>() {
| +++++++++++++++++++++++++++++++++++
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<const P: Point>() {}
| ^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_point`
error: the constant `MyEnum::<u32>::Variant` is not of type `MyEnum<u32>`
--> $DIR/tuple_ctor_erroneous.rs:42:22
--> $DIR/tuple_ctor_erroneous.rs:43:22
|
LL | accepts_enum::<{ MyEnum::Variant::<u32> }>();
| ^^^^^^^^^^^^^^^^^^^^^^ expected `MyEnum<u32>`, 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<const E: MyEnum<u32>>() {}
| ^^^^^^^^^^^^^^^^^^^^ required by this const generic parameter in `accepts_enum`

View file

@ -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]`
}

View file

@ -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