Auto merge of #152213 - JonathanBrouwer:rollup-trjCgZZ, r=JonathanBrouwer

Rollup of 13 pull requests

Successful merges:

 - rust-lang/rust#152191 (Convert to inline diagnostics in `rustc_hir_analysis`)
 - rust-lang/rust#149329 (Mark match arms in try and for as being from desugarings.)
 - rust-lang/rust#151474 (Minor structural improvements)
 - rust-lang/rust#152107 (Convert to inline diagnostics in `rustc_borrowck`)
 - rust-lang/rust#152117 (Convert to inline diagnostics in `rustc_trait_selection`)
 - rust-lang/rust#152136 (Consolidate type const checks on `tcx.is_type_const`)
 - rust-lang/rust#152140 (Hard code the error code registry for custom drivers)
 - rust-lang/rust#152155 (Fix typos in riscv64a23-unknown-linux-gnu.md)
 - rust-lang/rust#152170 (Port `rustc_effective_visibility` to the new attribute parser)
 - rust-lang/rust#152182 (update compiler stable backport zulip msg)
 - rust-lang/rust#152184 (Port rustc_abi to the attribute parser)
 - rust-lang/rust#152195 (update openmp/offload builds to LLVM 22, Part 1)
 - rust-lang/rust#152202 (chore: clearify tidy's error message)

Failed merges:

 - rust-lang/rust#151744 (fix refining_impl_trait suggestion with return_type_notation)
 - rust-lang/rust#152212 (Port some attributes to the attr parser)
This commit is contained in:
bors 2026-02-06 09:12:28 +00:00
commit 035b01b794
75 changed files with 2091 additions and 2647 deletions

View file

@ -3571,7 +3571,6 @@ dependencies = [
"rustc_abi",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_graphviz",
"rustc_hir",
"rustc_index",
@ -3771,7 +3770,6 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_borrowck",
"rustc_codegen_ssa",
"rustc_const_eval",
"rustc_data_structures",
@ -3797,7 +3795,6 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"serde_json",
"shlex",
"tracing",
@ -3959,7 +3956,6 @@ dependencies = [
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_hir",
"rustc_index",
"rustc_infer",
@ -4723,7 +4719,6 @@ dependencies = [
"rustc_ast",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
"rustc_hir",
"rustc_infer",
"rustc_macros",

View file

@ -966,14 +966,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::ExprKind::Break(this.lower_loop_destination(None), Some(x_expr));
this.arena.alloc(this.expr(gen_future_span, expr_break))
});
self.arm(ready_pat, break_x)
self.arm(ready_pat, break_x, span)
};
// `::std::task::Poll::Pending => {}`
let pending_arm = {
let pending_pat = self.pat_lang_item_variant(span, hir::LangItem::PollPending, &[]);
let empty_block = self.expr_block_empty(span);
self.arm(pending_pat, empty_block)
self.arm(pending_pat, empty_block, span)
};
let inner_match_stmt = {
@ -1027,7 +1027,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
// mut __awaitee => loop { ... }
let awaitee_arm = self.arm(awaitee_pat, loop_expr);
let awaitee_arm = self.arm(awaitee_pat, loop_expr, span);
// `match ::std::future::IntoFuture::into_future(<expr>) { ... }`
let into_future_expr = match await_kind {
@ -1817,7 +1817,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let break_expr =
self.with_loop_scope(loop_hir_id, |this| this.expr_break_alloc(for_span));
let pat = self.pat_none(for_span);
self.arm(pat, break_expr)
self.arm(pat, break_expr, for_span)
};
// Some(<pat>) => <body>,
@ -1826,7 +1826,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let body_block =
self.with_loop_scope(loop_hir_id, |this| this.lower_block(body, false));
let body_expr = self.arena.alloc(self.expr_block(body_block));
self.arm(some_pat, body_expr)
self.arm(some_pat, body_expr, for_span)
};
// `mut iter`
@ -1885,7 +1885,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let loop_expr = self.arena.alloc(hir::Expr { hir_id: loop_hir_id, kind, span: for_span });
// `mut iter => { ... }`
let iter_arm = self.arm(iter_pat, loop_expr);
let iter_arm = self.arm(iter_pat, loop_expr, for_span);
let match_expr = match loop_kind {
ForLoopKind::For => {
@ -1930,7 +1930,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
hir::LangItem::IntoAsyncIterIntoIter,
arena_vec![self; head],
);
let iter_arm = self.arm(async_iter_pat, inner_match_expr);
let iter_arm = self.arm(async_iter_pat, inner_match_expr, for_span);
self.arena.alloc(self.expr_match(
for_span,
iter,
@ -1997,7 +1997,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let val_expr = self.expr_ident(span, val_ident, val_pat_nid);
self.lower_attrs(val_expr.hir_id, &attrs, span, Target::Expression);
let continue_pat = self.pat_cf_continue(unstable_span, val_pat);
self.arm(continue_pat, val_expr)
self.arm(continue_pat, val_expr, try_span)
};
// `ControlFlow::Break(residual) =>
@ -2040,7 +2040,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
self.lower_attrs(ret_expr.hir_id, &attrs, span, Target::Expression);
let break_pat = self.pat_cf_break(try_span, residual_local);
self.arm(break_pat, ret_expr)
self.arm(break_pat, ret_expr, try_span)
};
hir::ExprKind::Match(
@ -2368,12 +2368,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self,
pat: &'hir hir::Pat<'hir>,
expr: &'hir hir::Expr<'hir>,
span: Span,
) -> hir::Arm<'hir> {
hir::Arm {
hir_id: self.next_id(),
pat,
guard: None,
span: self.lower_span(expr.span),
span: self.lower_span(span),
body: expr,
}
}

View file

@ -721,3 +721,42 @@ impl<S: Stage> CombineAttributeParser<S> for RustcThenThisWouldNeedParser {
Some(ident)
}
}
pub(crate) struct RustcEffectiveVisibilityParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
const PATH: &'static [Symbol] = &[sym::rustc_effective_visibility];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Use),
Allow(Target::Static),
Allow(Target::Const),
Allow(Target::Fn),
Allow(Target::Closure),
Allow(Target::Mod),
Allow(Target::ForeignMod),
Allow(Target::TyAlias),
Allow(Target::Enum),
Allow(Target::Variant),
Allow(Target::Struct),
Allow(Target::Field),
Allow(Target::Union),
Allow(Target::Trait),
Allow(Target::TraitAlias),
Allow(Target::Impl { of_trait: false }),
Allow(Target::Impl { of_trait: true }),
Allow(Target::AssocConst),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::TraitImpl)),
Allow(Target::AssocTy),
Allow(Target::ForeignFn),
Allow(Target::ForeignStatic),
Allow(Target::ForeignTy),
Allow(Target::MacroDef),
Allow(Target::PatField),
Allow(Target::Crate),
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility;
}

View file

@ -1,3 +1,4 @@
use rustc_hir::attrs::RustcAbiAttrKind;
use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT;
use super::prelude::*;
@ -140,3 +141,52 @@ impl<S: Stage> SingleAttributeParser<S> for ReexportTestHarnessMainParser {
Some(AttributeKind::ReexportTestHarnessMain(name))
}
}
pub(crate) struct RustcAbiParser;
impl<S: Stage> SingleAttributeParser<S> for RustcAbiParser {
const PATH: &[Symbol] = &[sym::rustc_abi];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const TEMPLATE: AttributeTemplate = template!(OneOf: &[sym::debug, sym::assert_eq]);
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::TyAlias),
Allow(Target::Fn),
Allow(Target::ForeignFn),
Allow(Target::Method(MethodKind::Inherent)),
Allow(Target::Method(MethodKind::Trait { body: true })),
Allow(Target::Method(MethodKind::Trait { body: false })),
Allow(Target::Method(MethodKind::TraitImpl)),
]);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(args) = args.list() else {
cx.expected_specific_argument_and_list(cx.attr_span, &[sym::assert_eq, sym::debug]);
return None;
};
let Some(arg) = args.single() else {
cx.expected_single_argument(cx.attr_span);
return None;
};
let fail_incorrect_argument =
|span| cx.expected_specific_argument(span, &[sym::assert_eq, sym::debug]);
let Some(arg) = arg.meta_item() else {
fail_incorrect_argument(args.span);
return None;
};
let kind: RustcAbiAttrKind = match arg.path().word_sym() {
Some(sym::assert_eq) => RustcAbiAttrKind::AssertEq,
Some(sym::debug) => RustcAbiAttrKind::Debug,
None | Some(_) => {
fail_incorrect_argument(arg.span());
return None;
}
};
Some(AttributeKind::RustcAbi { attr_span: cx.attr_span, kind })
}
}

View file

@ -191,6 +191,7 @@ attribute_parsers!(
Single<ProcMacroDeriveParser>,
Single<RecursionLimitParser>,
Single<ReexportTestHarnessMainParser>,
Single<RustcAbiParser>,
Single<RustcAllocatorZeroedVariantParser>,
Single<RustcBuiltinMacroParser>,
Single<RustcForceInlineParser>,
@ -258,6 +259,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcDumpPredicatesParser>>,
Single<WithoutArgs<RustcDumpUserArgsParser>>,
Single<WithoutArgs<RustcDumpVtableParser>>,
Single<WithoutArgs<RustcEffectiveVisibilityParser>>,
Single<WithoutArgs<RustcHasIncoherentInherentImplsParser>>,
Single<WithoutArgs<RustcHiddenTypeOfOpaquesParser>>,
Single<WithoutArgs<RustcLintOptTyParser>>,

View file

@ -11,7 +11,6 @@ polonius-engine = "0.13.0"
rustc_abi = { path = "../rustc_abi" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_graphviz = { path = "../rustc_graphviz" }
rustc_hir = { path = "../rustc_hir" }
rustc_index = { path = "../rustc_index" }

View file

@ -1,296 +0,0 @@
borrowck_assign_due_to_use_closure =
assignment occurs due to use in closure
borrowck_assign_due_to_use_coroutine =
assign occurs due to use in coroutine
borrowck_assign_part_due_to_use_closure =
assignment to part occurs due to use in closure
borrowck_assign_part_due_to_use_coroutine =
assign to part occurs due to use in coroutine
borrowck_borrow_due_to_use_closure =
borrow occurs due to use in closure
borrowck_borrow_due_to_use_coroutine =
borrow occurs due to use in coroutine
borrowck_calling_operator_moves =
calling this operator moves the value
borrowck_calling_operator_moves_lhs =
calling this operator moves the left-hand side
borrowck_cannot_move_when_borrowed =
cannot move out of {$place ->
[value] value
*[other] {$place}
} because it is borrowed
.label = borrow of {$borrow_place ->
[value] value
*[other] {$borrow_place}
} occurs here
.move_label = move out of {$value_place ->
[value] value
*[other] {$value_place}
} occurs here
borrowck_capture_immute =
capture is immutable because of use here
borrowck_capture_move =
capture is moved because of use here
borrowck_capture_mut =
capture is mutable because of use here
borrowck_closure_inferred_mut = inferred to be a `FnMut` closure
borrowck_closure_invoked_twice =
closure cannot be invoked more than once because it moves the variable `{$place_name}` out of its environment
borrowck_closure_moved_twice =
closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place_name}` out of its environment
borrowck_consider_borrow_type_contents =
help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
borrowck_could_not_normalize =
could not normalize `{$value}`
borrowck_could_not_prove =
could not prove `{$predicate}`
borrowck_dereference_suggestion =
dereference the return value
borrowck_func_take_self_moved_place =
`{$func}` takes ownership of the receiver `self`, which moves {$place_name}
borrowck_generic_does_not_live_long_enough =
`{$kind}` does not live long enough
borrowck_higher_ranked_lifetime_error =
higher-ranked lifetime error
borrowck_higher_ranked_subtype_error =
higher-ranked subtype error
borrowck_implicit_static =
this has an implicit `'static` lifetime requirement
borrowck_implicit_static_introduced =
calling this method introduces the `impl`'s `'static` requirement
borrowck_implicit_static_relax =
consider relaxing the implicit `'static` requirement
borrowck_lifetime_constraints_error =
lifetime may not live long enough
borrowck_limitations_implies_static =
due to a current limitation of the type system, this implies a `'static` lifetime
borrowck_move_closure_suggestion =
consider adding 'move' keyword before the nested closure
borrowck_move_out_place_here =
{$place} is moved here
borrowck_move_unsized =
cannot move a value of type `{$ty}`
.label = the size of `{$ty}` cannot be statically determined
borrowck_moved_a_fn_once_in_call =
this value implements `FnOnce`, which causes it to be moved when called
borrowck_moved_a_fn_once_in_call_call =
`FnOnce` closures can only be called once
borrowck_moved_a_fn_once_in_call_def =
`{$ty}` is made to be an `FnOnce` closure here
borrowck_moved_due_to_await =
{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this {$is_loop_message ->
[true] await, in previous iteration of loop
*[false] await
}
borrowck_moved_due_to_call =
{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this {$is_loop_message ->
[true] call, in previous iteration of loop
*[false] call
}
borrowck_moved_due_to_implicit_into_iter_call =
{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this implicit call to {$is_loop_message ->
[true] `.into_iter()`, in previous iteration of loop
*[false] `.into_iter()`
}
borrowck_moved_due_to_method_call =
{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this method {$is_loop_message ->
[true] call, in previous iteration of loop
*[false] call
}
borrowck_moved_due_to_usage_in_operator =
{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to usage in {$is_loop_message ->
[true] operator, in previous iteration of loop
*[false] operator
}
borrowck_opaque_type_lifetime_mismatch =
opaque type used twice with different lifetimes
.label = lifetime `{$arg}` used here
.prev_lifetime_label = lifetime `{$prev}` previously used here
.note = if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types
borrowck_partial_var_move_by_use_in_closure =
variable {$is_partial ->
[true] partially moved
*[false] moved
} due to use in closure
borrowck_partial_var_move_by_use_in_coroutine =
variable {$is_partial ->
[true] partially moved
*[false] moved
} due to use in coroutine
borrowck_restrict_to_static =
consider restricting the type parameter to the `'static` lifetime
borrowck_returned_async_block_escaped =
returns an `async` block that contains a reference to a captured variable, which then escapes the closure body
borrowck_returned_closure_escaped =
returns a closure that contains a reference to a captured variable, which then escapes the closure body
borrowck_returned_lifetime_short =
{$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`
borrowck_returned_lifetime_wrong =
{$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}`
borrowck_returned_ref_escaped =
returns a reference to a captured variable which escapes the closure body
borrowck_simd_intrinsic_arg_const =
{$arg ->
[1] 1st
[2] 2nd
[3] 3rd
*[other] {$arg}th
} argument of `{$intrinsic}` is required to be a `const` item
borrowck_suggest_create_fresh_reborrow =
consider reborrowing the `Pin` instead of moving it
borrowck_suggest_iterate_over_slice =
consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop
borrowck_tail_expr_drop_order = relative drop order changing in Rust 2024
.label = this temporary value will be dropped at the end of the block
.note = consider using a `let` binding to ensure the value will live long enough
borrowck_ty_no_impl_copy =
{$is_partial_move ->
[true] partial move
*[false] move
} occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait
borrowck_use_due_to_use_closure =
use occurs due to use in closure
borrowck_use_due_to_use_coroutine =
use occurs due to use in coroutine
borrowck_used_impl_require_static =
the used `impl` has a `'static` requirement
borrowck_value_capture_here =
value captured {$is_within ->
[true] here by coroutine
*[false] here
}
borrowck_value_moved_here =
value {$is_partial ->
[true] partially moved
*[false] moved
} {$is_move_msg ->
[true] into closure here
*[false] here
}{$is_loop_message ->
[true] , in previous iteration of loop
*[false] {""}
}
borrowck_var_borrow_by_use_in_closure =
borrow occurs due to use in closure
borrowck_var_borrow_by_use_in_coroutine =
borrow occurs due to use in coroutine
borrowck_var_borrow_by_use_place_in_closure =
{$is_single_var ->
*[true] borrow occurs
[false] borrows occur
} due to use of {$place} in closure
borrowck_var_borrow_by_use_place_in_coroutine =
{$is_single_var ->
*[true] borrow occurs
[false] borrows occur
} due to use of {$place} in coroutine
borrowck_var_cannot_escape_closure =
captured variable cannot escape `FnMut` closure body
.note = `FnMut` closures only have access to their captured variables while they are executing...
.cannot_escape = ...therefore, they cannot allow references to captured variables to escape
borrowck_var_does_not_need_mut =
variable does not need to be mutable
.suggestion = remove this `mut`
borrowck_var_first_borrow_by_use_place_in_closure =
first borrow occurs due to use of {$place} in closure
borrowck_var_first_borrow_by_use_place_in_coroutine =
first borrow occurs due to use of {$place} in coroutine
borrowck_var_here_captured = variable captured here
borrowck_var_here_defined = variable defined here
borrowck_var_move_by_use_in_closure =
move occurs due to use in closure
borrowck_var_move_by_use_in_coroutine =
move occurs due to use in coroutine
borrowck_var_mutable_borrow_by_use_place_in_closure =
mutable borrow occurs due to use of {$place} in closure
borrowck_var_second_borrow_by_use_place_in_closure =
second borrow occurs due to use of {$place} in closure
borrowck_var_second_borrow_by_use_place_in_coroutine =
second borrow occurs due to use of {$place} in coroutine

View file

@ -4,7 +4,9 @@ use std::collections::BTreeMap;
use rustc_abi::{FieldIdx, VariantIdx};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::{Applicability, Diag, EmissionGuarantee, MultiSpan, listify};
use rustc_errors::{
Applicability, Diag, DiagMessage, EmissionGuarantee, MultiSpan, inline_fluent, listify,
};
use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::{
self as hir, CoroutineKind, GenericBound, LangItem, WhereBoundPredicate, WherePredicateKind,
@ -35,7 +37,6 @@ use tracing::debug;
use super::MirBorrowckCtxt;
use super::borrow_set::BorrowData;
use crate::constraints::OutlivesConstraint;
use crate::fluent_generated as fluent;
use crate::nll::ConstraintDescription;
use crate::session_diagnostics::{
CaptureArgLabel, CaptureReasonLabel, CaptureReasonNote, CaptureReasonSuggest, CaptureVarCause,
@ -700,7 +701,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
.rfind(|bgp| tcx.local_def_id_to_hir_id(bgp.def_id) == gat_hir_id)
.is_some()
{
diag.span_note(pred.span, fluent::borrowck_limitations_implies_static);
diag.span_note(pred.span, LIMITATION_NOTE);
return;
}
for bound in bounds.iter() {
@ -711,7 +712,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
.rfind(|bgp| tcx.local_def_id_to_hir_id(bgp.def_id) == gat_hir_id)
.is_some()
{
diag.span_note(bound.span, fluent::borrowck_limitations_implies_static);
diag.span_note(bound.span, LIMITATION_NOTE);
return;
}
}
@ -1312,7 +1313,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let mut span: MultiSpan = spans.clone().into();
err.arg("ty", param_ty.to_string());
let msg = err.dcx.eagerly_translate_to_string(
fluent::borrowck_moved_a_fn_once_in_call_def,
inline_fluent!("`{$ty}` is made to be an `FnOnce` closure here"),
err.args.iter(),
);
err.remove_arg("ty");
@ -1321,9 +1322,12 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
}
span.push_span_label(
fn_call_span,
fluent::borrowck_moved_a_fn_once_in_call,
inline_fluent!("this value implements `FnOnce`, which causes it to be moved when called"),
);
err.span_note(
span,
inline_fluent!("`FnOnce` closures can only be called once"),
);
err.span_note(span, fluent::borrowck_moved_a_fn_once_in_call_call);
} else {
err.subdiagnostic(CaptureReasonNote::FnOnceMoveInCall { var_span });
}
@ -1568,3 +1572,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
self.local_name(index).is_none_or(|name| name.as_str().starts_with('_'))
}
}
const LIMITATION_NOTE: DiagMessage = inline_fluent!(
"due to a current limitation of the type system, this implies a `'static` lifetime"
);

View file

@ -1,7 +1,7 @@
//! Error reporting machinery for lifetime errors.
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan};
use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, inline_fluent};
use rustc_hir as hir;
use rustc_hir::GenericBound::Trait;
use rustc_hir::QPath::Resolved;
@ -27,7 +27,7 @@ use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{Obligation, ObligationCtxt};
use tracing::{debug, instrument, trace};
use super::{OutlivesSuggestionBuilder, RegionName, RegionNameSource};
use super::{LIMITATION_NOTE, OutlivesSuggestionBuilder, RegionName, RegionNameSource};
use crate::nll::ConstraintDescription;
use crate::region_infer::values::RegionElement;
use crate::region_infer::{BlameConstraint, TypeTest};
@ -36,7 +36,7 @@ use crate::session_diagnostics::{
LifetimeReturnCategoryErr, RequireStaticErr, VarHereDenote,
};
use crate::universal_regions::DefiningTy;
use crate::{MirBorrowckCtxt, borrowck_errors, fluent_generated as fluent};
use crate::{MirBorrowckCtxt, borrowck_errors};
impl<'tcx> ConstraintDescription for ConstraintCategory<'tcx> {
fn description(&self) -> &'static str {
@ -265,7 +265,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }) = bound else {
return;
};
diag.span_note(*trait_span, fluent::borrowck_limitations_implies_static);
diag.span_note(*trait_span, LIMITATION_NOTE);
let Some(generics_fn) = tcx.hir_get_generics(self.body.source.def_id().expect_local())
else {
return;
@ -298,7 +298,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if suggestions.len() > 0 {
suggestions.dedup();
diag.multipart_suggestion_verbose(
fluent::borrowck_restrict_to_static,
inline_fluent!("consider restricting the type parameter to the `'static` lifetime"),
suggestions,
Applicability::MaybeIncorrect,
);
@ -966,12 +966,20 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
debug!("trait spans found: {:?}", traits);
for span in &traits {
let mut multi_span: MultiSpan = vec![*span].into();
multi_span.push_span_label(*span, fluent::borrowck_implicit_static);
multi_span.push_span_label(ident.span, fluent::borrowck_implicit_static_introduced);
multi_span.push_span_label(
*span,
inline_fluent!("this has an implicit `'static` lifetime requirement"),
);
multi_span.push_span_label(
ident.span,
inline_fluent!(
"calling this method introduces the `impl`'s `'static` requirement"
),
);
err.subdiagnostic(RequireStaticErr::UsedImpl { multi_span });
err.span_suggestion_verbose(
span.shrink_to_hi(),
fluent::borrowck_implicit_static_relax,
inline_fluent!("consider relaxing the implicit `'static` requirement"),
" + '_",
Applicability::MaybeIncorrect,
);
@ -1134,7 +1142,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if ocx.evaluate_obligations_error_on_ambiguity().is_empty() && count > 0 {
diag.span_suggestion_verbose(
tcx.hir_body(*body).value.peel_blocks().span.shrink_to_lo(),
fluent::borrowck_dereference_suggestion,
inline_fluent!("dereference the return value"),
"*".repeat(count),
Applicability::MachineApplicable,
);
@ -1178,7 +1186,7 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
if let Some(closure_span) = closure_span {
diag.span_suggestion_verbose(
closure_span,
fluent::borrowck_move_closure_suggestion,
inline_fluent!("consider adding 'move' keyword before the nested closure"),
"move ",
Applicability::MaybeIncorrect,
);

View file

@ -99,8 +99,6 @@ mod used_muts;
/// A public API provided for the Rust compiler consumers.
pub mod consumers;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
/// Associate some local constants with the `'tcx` lifetime
struct TyCtxtConsts<'tcx>(PhantomData<&'tcx ()>);

View file

@ -7,16 +7,16 @@ use rustc_span::Span;
use crate::diagnostics::RegionName;
#[derive(Diagnostic)]
#[diag(borrowck_move_unsized, code = E0161)]
#[diag("cannot move a value of type `{$ty}`", code = E0161)]
pub(crate) struct MoveUnsized<'tcx> {
pub ty: Ty<'tcx>,
#[primary_span]
#[label]
#[label("the size of `{$ty}` cannot be statically determined")]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(borrowck_higher_ranked_lifetime_error)]
#[diag("higher-ranked lifetime error")]
pub(crate) struct HigherRankedLifetimeError {
#[subdiagnostic]
pub cause: Option<HigherRankedErrorCause>,
@ -26,21 +26,21 @@ pub(crate) struct HigherRankedLifetimeError {
#[derive(Subdiagnostic)]
pub(crate) enum HigherRankedErrorCause {
#[note(borrowck_could_not_prove)]
#[note("could not prove `{$predicate}`")]
CouldNotProve { predicate: String },
#[note(borrowck_could_not_normalize)]
#[note("could not normalize `{$value}`")]
CouldNotNormalize { value: String },
}
#[derive(Diagnostic)]
#[diag(borrowck_higher_ranked_subtype_error)]
#[diag("higher-ranked subtype error")]
pub(crate) struct HigherRankedSubtypeError {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(borrowck_generic_does_not_live_long_enough)]
#[diag("`{$kind}` does not live long enough")]
pub(crate) struct GenericDoesNotLiveLongEnough {
pub kind: String,
#[primary_span]
@ -48,15 +48,20 @@ pub(crate) struct GenericDoesNotLiveLongEnough {
}
#[derive(LintDiagnostic)]
#[diag(borrowck_var_does_not_need_mut)]
#[diag("variable does not need to be mutable")]
pub(crate) struct VarNeedNotMut {
#[suggestion(style = "short", applicability = "machine-applicable", code = "")]
#[suggestion(
"remove this `mut`",
style = "short",
applicability = "machine-applicable",
code = ""
)]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(borrowck_var_cannot_escape_closure)]
#[note]
#[note(borrowck_cannot_escape)]
#[diag("captured variable cannot escape `FnMut` closure body")]
#[note("`FnMut` closures only have access to their captured variables while they are executing...")]
#[note("...therefore, they cannot allow references to captured variables to escape")]
pub(crate) struct FnMutError {
#[primary_span]
pub span: Span,
@ -66,17 +71,17 @@ pub(crate) struct FnMutError {
#[derive(Subdiagnostic)]
pub(crate) enum VarHereDenote {
#[label(borrowck_var_here_captured)]
#[label("variable captured here")]
Captured {
#[primary_span]
span: Span,
},
#[label(borrowck_var_here_defined)]
#[label("variable defined here")]
Defined {
#[primary_span]
span: Span,
},
#[label(borrowck_closure_inferred_mut)]
#[label("inferred to be a `FnMut` closure")]
FnMutInferred {
#[primary_span]
span: Span,
@ -85,17 +90,21 @@ pub(crate) enum VarHereDenote {
#[derive(Subdiagnostic)]
pub(crate) enum FnMutReturnTypeErr {
#[label(borrowck_returned_closure_escaped)]
#[label(
"returns a closure that contains a reference to a captured variable, which then escapes the closure body"
)]
ReturnClosure {
#[primary_span]
span: Span,
},
#[label(borrowck_returned_async_block_escaped)]
#[label(
"returns an `async` block that contains a reference to a captured variable, which then escapes the closure body"
)]
ReturnAsyncBlock {
#[primary_span]
span: Span,
},
#[label(borrowck_returned_ref_escaped)]
#[label("returns a reference to a captured variable which escapes the closure body")]
ReturnRef {
#[primary_span]
span: Span,
@ -103,7 +112,7 @@ pub(crate) enum FnMutReturnTypeErr {
}
#[derive(Diagnostic)]
#[diag(borrowck_lifetime_constraints_error)]
#[diag("lifetime may not live long enough")]
pub(crate) struct LifetimeOutliveErr {
#[primary_span]
pub span: Span,
@ -111,7 +120,9 @@ pub(crate) struct LifetimeOutliveErr {
#[derive(Subdiagnostic)]
pub(crate) enum LifetimeReturnCategoryErr<'a> {
#[label(borrowck_returned_lifetime_wrong)]
#[label(
"{$mir_def_name} was supposed to return data with lifetime `{$outlived_fr_name}` but it is returning data with lifetime `{$fr_name}`"
)]
WrongReturn {
#[primary_span]
span: Span,
@ -119,7 +130,9 @@ pub(crate) enum LifetimeReturnCategoryErr<'a> {
outlived_fr_name: RegionName,
fr_name: &'a RegionName,
},
#[label(borrowck_returned_lifetime_short)]
#[label(
"{$category_desc}requires that `{$free_region_name}` must outlive `{$outlived_fr_name}`"
)]
ShortReturn {
#[primary_span]
span: Span,
@ -131,7 +144,7 @@ pub(crate) enum LifetimeReturnCategoryErr<'a> {
#[derive(Subdiagnostic)]
pub(crate) enum RequireStaticErr {
#[note(borrowck_used_impl_require_static)]
#[note("the used `impl` has a `'static` requirement")]
UsedImpl {
#[primary_span]
multi_span: MultiSpan,
@ -140,42 +153,42 @@ pub(crate) enum RequireStaticErr {
#[derive(Subdiagnostic)]
pub(crate) enum CaptureVarPathUseCause {
#[label(borrowck_borrow_due_to_use_coroutine)]
#[label("borrow occurs due to use in coroutine")]
BorrowInCoroutine {
#[primary_span]
path_span: Span,
},
#[label(borrowck_use_due_to_use_coroutine)]
#[label("use occurs due to use in coroutine")]
UseInCoroutine {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_due_to_use_coroutine)]
#[label("assign occurs due to use in coroutine")]
AssignInCoroutine {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_part_due_to_use_coroutine)]
#[label("assign to part occurs due to use in coroutine")]
AssignPartInCoroutine {
#[primary_span]
path_span: Span,
},
#[label(borrowck_borrow_due_to_use_closure)]
#[label("borrow occurs due to use in closure")]
BorrowInClosure {
#[primary_span]
path_span: Span,
},
#[label(borrowck_use_due_to_use_closure)]
#[label("use occurs due to use in closure")]
UseInClosure {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_due_to_use_closure)]
#[label("assignment occurs due to use in closure")]
AssignInClosure {
#[primary_span]
path_span: Span,
},
#[label(borrowck_assign_part_due_to_use_closure)]
#[label("assignment to part occurs due to use in closure")]
AssignPartInClosure {
#[primary_span]
path_span: Span,
@ -184,17 +197,17 @@ pub(crate) enum CaptureVarPathUseCause {
#[derive(Subdiagnostic)]
pub(crate) enum CaptureVarKind {
#[label(borrowck_capture_immute)]
#[label("capture is immutable because of use here")]
Immut {
#[primary_span]
kind_span: Span,
},
#[label(borrowck_capture_mut)]
#[label("capture is mutable because of use here")]
Mut {
#[primary_span]
kind_span: Span,
},
#[label(borrowck_capture_move)]
#[label("capture is moved because of use here")]
Move {
#[primary_span]
kind_span: Span,
@ -203,77 +216,97 @@ pub(crate) enum CaptureVarKind {
#[derive(Subdiagnostic)]
pub(crate) enum CaptureVarCause {
#[label(borrowck_var_borrow_by_use_place_in_coroutine)]
#[label(
"{$is_single_var ->
*[true] borrow occurs
[false] borrows occur
} due to use of {$place} in coroutine"
)]
BorrowUsePlaceCoroutine {
is_single_var: bool,
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_borrow_by_use_place_in_closure)]
#[label(
"{$is_single_var ->
*[true] borrow occurs
[false] borrows occur
} due to use of {$place} in closure"
)]
BorrowUsePlaceClosure {
is_single_var: bool,
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_borrow_by_use_in_coroutine)]
#[label("borrow occurs due to use in coroutine")]
BorrowUseInCoroutine {
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_borrow_by_use_in_closure)]
#[label("borrow occurs due to use in closure")]
BorrowUseInClosure {
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_move_by_use_in_coroutine)]
#[label("move occurs due to use in coroutine")]
MoveUseInCoroutine {
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_move_by_use_in_closure)]
#[label("move occurs due to use in closure")]
MoveUseInClosure {
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_first_borrow_by_use_place_in_coroutine)]
#[label("first borrow occurs due to use of {$place} in coroutine")]
FirstBorrowUsePlaceCoroutine {
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_first_borrow_by_use_place_in_closure)]
#[label("first borrow occurs due to use of {$place} in closure")]
FirstBorrowUsePlaceClosure {
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_second_borrow_by_use_place_in_coroutine)]
#[label("second borrow occurs due to use of {$place} in coroutine")]
SecondBorrowUsePlaceCoroutine {
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_second_borrow_by_use_place_in_closure)]
#[label("second borrow occurs due to use of {$place} in closure")]
SecondBorrowUsePlaceClosure {
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_var_mutable_borrow_by_use_place_in_closure)]
#[label("mutable borrow occurs due to use of {$place} in closure")]
MutableBorrowUsePlaceClosure {
place: String,
#[primary_span]
var_span: Span,
},
#[label(borrowck_partial_var_move_by_use_in_coroutine)]
#[label(
"variable {$is_partial ->
[true] partially moved
*[false] moved
} due to use in coroutine"
)]
PartialMoveUseInCoroutine {
#[primary_span]
var_span: Span,
is_partial: bool,
},
#[label(borrowck_partial_var_move_by_use_in_closure)]
#[label(
"variable {$is_partial ->
[true] partially moved
*[false] moved
} due to use in closure"
)]
PartialMoveUseInClosure {
#[primary_span]
var_span: Span,
@ -282,34 +315,57 @@ pub(crate) enum CaptureVarCause {
}
#[derive(Diagnostic)]
#[diag(borrowck_cannot_move_when_borrowed, code = E0505)]
#[diag("cannot move out of {$place ->
[value] value
*[other] {$place}
} because it is borrowed", code = E0505)]
pub(crate) struct MoveBorrow<'a> {
pub place: &'a str,
pub borrow_place: &'a str,
pub value_place: &'a str,
#[primary_span]
#[label(borrowck_move_label)]
#[label(
"move out of {$value_place ->
[value] value
*[other] {$value_place}
} occurs here"
)]
pub span: Span,
#[label]
#[label(
"borrow of {$borrow_place ->
[value] value
*[other] {$borrow_place}
} occurs here"
)]
pub borrow_span: Span,
}
#[derive(Diagnostic)]
#[diag(borrowck_opaque_type_lifetime_mismatch)]
#[diag("opaque type used twice with different lifetimes")]
pub(crate) struct LifetimeMismatchOpaqueParam<'tcx> {
pub arg: GenericArg<'tcx>,
pub prev: GenericArg<'tcx>,
#[primary_span]
#[label]
#[note]
#[label("lifetime `{$arg}` used here")]
#[note(
"if all non-lifetime generic parameters are the same, but the lifetime parameters differ, it is not possible to differentiate the opaque types"
)]
pub span: Span,
#[label(borrowck_prev_lifetime_label)]
#[label("lifetime `{$prev}` previously used here")]
pub prev_span: Span,
}
#[derive(Subdiagnostic)]
pub(crate) enum CaptureReasonLabel<'a> {
#[label(borrowck_moved_due_to_call)]
#[label(
"{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this {$is_loop_message ->
[true] call, in previous iteration of loop
*[false] call
}"
)]
Call {
#[primary_span]
fn_call_span: Span,
@ -317,7 +373,15 @@ pub(crate) enum CaptureReasonLabel<'a> {
is_partial: bool,
is_loop_message: bool,
},
#[label(borrowck_moved_due_to_usage_in_operator)]
#[label(
"{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to usage in {$is_loop_message ->
[true] operator, in previous iteration of loop
*[false] operator
}"
)]
OperatorUse {
#[primary_span]
fn_call_span: Span,
@ -325,7 +389,15 @@ pub(crate) enum CaptureReasonLabel<'a> {
is_partial: bool,
is_loop_message: bool,
},
#[label(borrowck_moved_due_to_implicit_into_iter_call)]
#[label(
"{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this implicit call to {$is_loop_message ->
[true] `.into_iter()`, in previous iteration of loop
*[false] `.into_iter()`
}"
)]
ImplicitCall {
#[primary_span]
fn_call_span: Span,
@ -333,7 +405,15 @@ pub(crate) enum CaptureReasonLabel<'a> {
is_partial: bool,
is_loop_message: bool,
},
#[label(borrowck_moved_due_to_method_call)]
#[label(
"{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this method {$is_loop_message ->
[true] call, in previous iteration of loop
*[false] call
}"
)]
MethodCall {
#[primary_span]
fn_call_span: Span,
@ -341,7 +421,15 @@ pub(crate) enum CaptureReasonLabel<'a> {
is_partial: bool,
is_loop_message: bool,
},
#[label(borrowck_moved_due_to_await)]
#[label(
"{$place_name} {$is_partial ->
[true] partially moved
*[false] moved
} due to this {$is_loop_message ->
[true] await, in previous iteration of loop
*[false] await
}"
)]
Await {
#[primary_span]
fn_call_span: Span,
@ -349,7 +437,18 @@ pub(crate) enum CaptureReasonLabel<'a> {
is_partial: bool,
is_loop_message: bool,
},
#[label(borrowck_value_moved_here)]
#[label(
"value {$is_partial ->
[true] partially moved
*[false] moved
} {$is_move_msg ->
[true] into closure here
*[false] here
}{$is_loop_message ->
[true] , in previous iteration of loop
*[false] {\"\"}
}"
)]
MovedHere {
#[primary_span]
move_span: Span,
@ -357,7 +456,7 @@ pub(crate) enum CaptureReasonLabel<'a> {
is_move_msg: bool,
is_loop_message: bool,
},
#[label(borrowck_consider_borrow_type_contents)]
#[label("help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents")]
BorrowContent {
#[primary_span]
var_span: Span,
@ -366,22 +465,22 @@ pub(crate) enum CaptureReasonLabel<'a> {
#[derive(Subdiagnostic)]
pub(crate) enum CaptureReasonNote {
#[note(borrowck_moved_a_fn_once_in_call)]
#[note("this value implements `FnOnce`, which causes it to be moved when called")]
FnOnceMoveInCall {
#[primary_span]
var_span: Span,
},
#[note(borrowck_calling_operator_moves)]
#[note("calling this operator moves the value")]
UnOpMoveByOperator {
#[primary_span]
span: Span,
},
#[note(borrowck_calling_operator_moves_lhs)]
#[note("calling this operator moves the left-hand side")]
LhsMoveByOperator {
#[primary_span]
span: Span,
},
#[note(borrowck_func_take_self_moved_place)]
#[note("`{$func}` takes ownership of the receiver `self`, which moves {$place_name}")]
FuncTakeSelf {
func: String,
place_name: String,
@ -393,7 +492,7 @@ pub(crate) enum CaptureReasonNote {
#[derive(Subdiagnostic)]
pub(crate) enum CaptureReasonSuggest<'tcx> {
#[suggestion(
borrowck_suggest_iterate_over_slice,
"consider iterating over a slice of the `{$ty}`'s content to avoid moving into the `for` loop",
applicability = "maybe-incorrect",
code = "&",
style = "verbose"
@ -404,7 +503,7 @@ pub(crate) enum CaptureReasonSuggest<'tcx> {
span: Span,
},
#[suggestion(
borrowck_suggest_create_fresh_reborrow,
"consider reborrowing the `Pin` instead of moving it",
applicability = "maybe-incorrect",
code = ".as_mut()",
style = "verbose"
@ -417,13 +516,18 @@ pub(crate) enum CaptureReasonSuggest<'tcx> {
#[derive(Subdiagnostic)]
pub(crate) enum CaptureArgLabel {
#[label(borrowck_value_capture_here)]
#[label(
"value captured {$is_within ->
[true] here by coroutine
*[false] here
}"
)]
Capture {
is_within: bool,
#[primary_span]
args_span: Span,
},
#[label(borrowck_move_out_place_here)]
#[label("{$place} is moved here")]
MoveOutPlace {
place: String,
#[primary_span]
@ -433,13 +537,17 @@ pub(crate) enum CaptureArgLabel {
#[derive(Subdiagnostic)]
pub(crate) enum OnClosureNote<'a> {
#[note(borrowck_closure_invoked_twice)]
#[note(
"closure cannot be invoked more than once because it moves the variable `{$place_name}` out of its environment"
)]
InvokedTwice {
place_name: &'a str,
#[primary_span]
span: Span,
},
#[note(borrowck_closure_moved_twice)]
#[note(
"closure cannot be moved more than once as it is not `Copy` due to moving the variable `{$place_name}` out of its environment"
)]
MovedTwice {
place_name: &'a str,
#[primary_span]
@ -449,7 +557,12 @@ pub(crate) enum OnClosureNote<'a> {
#[derive(Subdiagnostic)]
pub(crate) enum TypeNoCopy<'a, 'tcx> {
#[label(borrowck_ty_no_impl_copy)]
#[label(
"{$is_partial_move ->
[true] partial move
*[false] move
} occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait"
)]
Label {
is_partial_move: bool,
ty: Ty<'tcx>,
@ -457,12 +570,24 @@ pub(crate) enum TypeNoCopy<'a, 'tcx> {
#[primary_span]
span: Span,
},
#[note(borrowck_ty_no_impl_copy)]
#[note(
"{$is_partial_move ->
[true] partial move
*[false] move
} occurs because {$place} has type `{$ty}`, which does not implement the `Copy` trait"
)]
Note { is_partial_move: bool, ty: Ty<'tcx>, place: &'a str },
}
#[derive(Diagnostic)]
#[diag(borrowck_simd_intrinsic_arg_const)]
#[diag(
"{$arg ->
[1] 1st
[2] 2nd
[3] 3rd
*[other] {$arg}th
} argument of `{$intrinsic}` is required to be a `const` item"
)]
pub(crate) struct SimdIntrinsicArgConst {
#[primary_span]
pub span: Span,
@ -471,8 +596,8 @@ pub(crate) struct SimdIntrinsicArgConst {
}
#[derive(LintDiagnostic)]
#[diag(borrowck_tail_expr_drop_order)]
#[diag("relative drop order changing in Rust 2024")]
pub(crate) struct TailExprDropOrder {
#[label]
#[label("this temporary value will be dropped at the end of the block")]
pub borrowed: Span,
}

View file

@ -1981,11 +1981,7 @@ impl SharedEmitter {
}
impl Emitter for SharedEmitter {
fn emit_diagnostic(
&mut self,
mut diag: rustc_errors::DiagInner,
_registry: &rustc_errors::registry::Registry,
) {
fn emit_diagnostic(&mut self, mut diag: rustc_errors::DiagInner) {
// Check that we aren't missing anything interesting when converting to
// the cut-down local `DiagInner`.
assert!(!diag.span.has_span_labels());

View file

@ -10,7 +10,6 @@ jiff = { version = "0.2.5", default-features = false, features = ["std"] }
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_const_eval = { path = "../rustc_const_eval" }
rustc_data_structures = { path = "../rustc_data_structures" }
@ -36,7 +35,6 @@ rustc_resolve = { path = "../rustc_resolve" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
serde_json = "1.0.59"
shlex = "1.0"
tracing = { version = "0.1.35" }

View file

@ -34,7 +34,6 @@ use rustc_data_structures::profiling::{
};
pub use rustc_errors::catch_fatal_errors;
use rustc_errors::emitter::stderr_destination;
use rustc_errors::registry::Registry;
use rustc_errors::translation::Translator;
use rustc_errors::{ColorConfig, DiagCtxt, ErrCode, PResult, markdown};
use rustc_feature::find_gated_cfg;
@ -114,14 +113,11 @@ pub fn default_translator() -> Translator {
pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
// tidy-alphabetical-start
rustc_borrowck::DEFAULT_LOCALE_RESOURCE,
rustc_const_eval::DEFAULT_LOCALE_RESOURCE,
rustc_hir_analysis::DEFAULT_LOCALE_RESOURCE,
rustc_lint::DEFAULT_LOCALE_RESOURCE,
rustc_mir_build::DEFAULT_LOCALE_RESOURCE,
rustc_parse::DEFAULT_LOCALE_RESOURCE,
rustc_passes::DEFAULT_LOCALE_RESOURCE,
rustc_trait_selection::DEFAULT_LOCALE_RESOURCE,
// tidy-alphabetical-end
];
@ -185,10 +181,6 @@ impl Callbacks for TimePassesCallbacks {
}
}
pub fn diagnostics_registry() -> Registry {
Registry::new(rustc_errors::codes::DIAGNOSTICS)
}
/// This is the primary entry point for rustc.
pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send)) {
let mut default_early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
@ -216,7 +208,7 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
let ice_file = ice_path_with_config(Some(&sopts.unstable_opts)).clone();
if let Some(ref code) = matches.opt_str("explain") {
handle_explain(&default_early_dcx, diagnostics_registry(), code, sopts.color);
handle_explain(&default_early_dcx, code, sopts.color);
return;
}
@ -243,7 +235,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))
override_queries: None,
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: diagnostics_registry(),
using_internal_features: &USING_INTERNAL_FEATURES,
};
@ -443,12 +434,12 @@ pub enum Compilation {
Continue,
}
fn handle_explain(early_dcx: &EarlyDiagCtxt, registry: Registry, code: &str, color: ColorConfig) {
fn handle_explain(early_dcx: &EarlyDiagCtxt, code: &str, color: ColorConfig) {
// Allow "E0123" or "0123" form.
let upper_cased_code = code.to_ascii_uppercase();
if let Ok(code) = upper_cased_code.trim_prefix('E').parse::<u32>()
&& code <= ErrCode::MAX_AS_U32
&& let Ok(description) = registry.try_find_description(ErrCode::from_u32(code))
&& let Ok(description) = rustc_errors::codes::try_find_description(ErrCode::from_u32(code))
{
let mut is_in_code_block = false;
let mut text = String::new();

View file

@ -192,7 +192,7 @@ pub fn fluent_bundle(
Ok(Some(bundle))
}
fn register_functions(bundle: &mut FluentBundle) {
pub fn register_functions<R, M>(bundle: &mut fluent_bundle::bundle::FluentBundle<R, M>) {
bundle
.add_function("STREQ", |positional, _named| match positional {
[FluentValue::String(a), FluentValue::String(b)] => format!("{}", (a == b)).into(),

View file

@ -27,7 +27,6 @@ use crate::emitter::{
ConfusionType, Destination, MAX_SUGGESTIONS, OutputTheme, detect_confusion_type, is_different,
normalize_whitespace, should_show_source_code,
};
use crate::registry::Registry;
use crate::translation::{Translator, to_fluent_args};
use crate::{
CodeSuggestion, DiagInner, DiagMessage, Emitter, ErrCode, Level, MultiSpan, Style, Subdiag,
@ -73,7 +72,7 @@ impl Debug for AnnotateSnippetEmitter {
impl Emitter for AnnotateSnippetEmitter {
/// The entry point for the diagnostics generation
fn emit_diagnostic(&mut self, mut diag: DiagInner, _registry: &Registry) {
fn emit_diagnostic(&mut self, mut diag: DiagInner) {
let fluent_args = to_fluent_args(diag.args.iter());
if self.track_diagnostics && diag.span.has_primary_spans() && !diag.span.is_dummy() {

View file

@ -5,6 +5,9 @@
//! long description text.
use std::fmt;
use std::sync::LazyLock;
use rustc_data_structures::fx::FxHashMap;
rustc_index::newtype_index! {
#[max = 9999] // Because all error codes have four digits.
@ -27,15 +30,28 @@ macro_rules! define_error_code_constants_and_diagnostics_table {
$(
pub const ${concat(E, $num)}: $crate::ErrCode = $crate::ErrCode::from_u32($num);
)*
pub static DIAGNOSTICS: &[($crate::ErrCode, &str)] = &[
$( (
${concat(E, $num)},
include_str!(
concat!("../../rustc_error_codes/src/error_codes/E", stringify!($num), ".md")
)
), )*
];
static DIAGNOSTICS: LazyLock<FxHashMap<ErrCode, &'static str>> = LazyLock::new(|| {
[
$( (
${concat(E, $num)},
include_str!(
concat!("../../rustc_error_codes/src/error_codes/E", stringify!($num), ".md")
)
), )*
]
.iter()
.copied()
.collect()
});
)
}
rustc_error_codes::error_codes!(define_error_code_constants_and_diagnostics_table);
#[derive(Debug)]
pub struct InvalidErrorCode;
/// Returns `InvalidErrorCode` if the code requested does not exist.
pub fn try_find_description(code: ErrCode) -> Result<&'static str, InvalidErrorCode> {
DIAGNOSTICS.get(&code).copied().ok_or(InvalidErrorCode)
}

View file

@ -24,7 +24,6 @@ use rustc_span::source_map::SourceMap;
use rustc_span::{FileName, SourceFile, Span};
use tracing::{debug, warn};
use crate::registry::Registry;
use crate::timings::TimingRecord;
use crate::translation::Translator;
use crate::{
@ -54,7 +53,7 @@ pub type DynEmitter = dyn Emitter + DynSend;
/// Emitter trait for emitting errors and other structured information.
pub trait Emitter {
/// Emit a structured diagnostic.
fn emit_diagnostic(&mut self, diag: DiagInner, registry: &Registry);
fn emit_diagnostic(&mut self, diag: DiagInner);
/// Emit a notification that an artifact has been output.
/// Currently only supported for the JSON format.
@ -66,7 +65,7 @@ pub trait Emitter {
/// Emit a report about future breakage.
/// Currently only supported for the JSON format.
fn emit_future_breakage_report(&mut self, _diags: Vec<DiagInner>, _registry: &Registry) {}
fn emit_future_breakage_report(&mut self, _diags: Vec<DiagInner>) {}
/// Emit list of unused externs.
/// Currently only supported for the JSON format.
@ -380,9 +379,9 @@ impl Emitter for EmitterWithNote {
None
}
fn emit_diagnostic(&mut self, mut diag: DiagInner, registry: &Registry) {
fn emit_diagnostic(&mut self, mut diag: DiagInner) {
diag.sub(Level::Note, self.note.clone(), MultiSpan::new());
self.emitter.emit_diagnostic(diag, registry);
self.emitter.emit_diagnostic(diag);
}
fn translator(&self) -> &Translator {
@ -399,7 +398,7 @@ impl Emitter for SilentEmitter {
None
}
fn emit_diagnostic(&mut self, _diag: DiagInner, _registry: &Registry) {}
fn emit_diagnostic(&mut self, _diag: DiagInner) {}
fn translator(&self) -> &Translator {
&self.translator

View file

@ -31,7 +31,6 @@ use crate::emitter::{
ColorConfig, Destination, Emitter, HumanReadableErrorType, OutputTheme, TimingEvent,
should_show_source_code,
};
use crate::registry::Registry;
use crate::timings::{TimingRecord, TimingSection};
use crate::translation::{Translator, to_fluent_args};
use crate::{CodeSuggestion, MultiSpan, SpanLabel, Subdiag, Suggestions, TerminalUrl};
@ -107,8 +106,8 @@ enum EmitTyped<'a> {
}
impl Emitter for JsonEmitter {
fn emit_diagnostic(&mut self, diag: crate::DiagInner, registry: &Registry) {
let data = Diagnostic::from_errors_diagnostic(diag, self, registry);
fn emit_diagnostic(&mut self, diag: crate::DiagInner) {
let data = Diagnostic::from_errors_diagnostic(diag, self);
let result = self.emit(EmitTyped::Diagnostic(data));
if let Err(e) = result {
panic!("failed to print diagnostics: {e:?}");
@ -139,7 +138,7 @@ impl Emitter for JsonEmitter {
}
}
fn emit_future_breakage_report(&mut self, diags: Vec<crate::DiagInner>, registry: &Registry) {
fn emit_future_breakage_report(&mut self, diags: Vec<crate::DiagInner>) {
let data: Vec<FutureBreakageItem<'_>> = diags
.into_iter()
.map(|mut diag| {
@ -153,7 +152,7 @@ impl Emitter for JsonEmitter {
}
FutureBreakageItem {
diagnostic: EmitTyped::Diagnostic(Diagnostic::from_errors_diagnostic(
diag, self, registry,
diag, self,
)),
}
})
@ -307,11 +306,7 @@ struct UnusedExterns<'a> {
impl Diagnostic {
/// Converts from `rustc_errors::DiagInner` to `Diagnostic`.
fn from_errors_diagnostic(
diag: crate::DiagInner,
je: &JsonEmitter,
registry: &Registry,
) -> Diagnostic {
fn from_errors_diagnostic(diag: crate::DiagInner, je: &JsonEmitter) -> Diagnostic {
let args = to_fluent_args(diag.args.iter());
let sugg_to_diag = |sugg: &CodeSuggestion| {
let translated_message =
@ -351,7 +346,7 @@ impl Diagnostic {
let code = if let Some(code) = diag.code {
Some(DiagnosticCode {
code: code.to_string(),
explanation: registry.try_find_description(code).ok(),
explanation: crate::codes::try_find_description(code).ok(),
})
} else if let Some(IsLint { name, .. }) = &diag.is_lint {
Some(DiagnosticCode { code: name.to_string(), explanation: None })
@ -388,7 +383,7 @@ impl Diagnostic {
.ui_testing(je.ui_testing)
.ignored_directories_in_source_blocks(je.ignored_directories_in_source_blocks.clone())
.theme(if je.json_rendered.unicode { OutputTheme::Unicode } else { OutputTheme::Ascii })
.emit_diagnostic(diag, registry);
.emit_diagnostic(diag);
let buf = Arc::try_unwrap(buf.0).unwrap().into_inner().unwrap();
let buf = String::from_utf8(buf).unwrap();

View file

@ -71,7 +71,6 @@ use rustc_span::{DUMMY_SP, Span};
use tracing::debug;
use crate::emitter::TimingEvent;
use crate::registry::Registry;
use crate::timings::TimingRecord;
pub mod annotate_snippet_emitter_writer;
@ -84,7 +83,6 @@ pub mod error;
pub mod json;
mod lock;
pub mod markdown;
pub mod registry;
#[cfg(test)]
mod tests;
pub mod timings;
@ -297,8 +295,6 @@ impl<'a> std::ops::Deref for DiagCtxtHandle<'a> {
struct DiagCtxtInner {
flags: DiagCtxtFlags,
registry: Registry,
/// The error guarantees from all emitted errors. The length gives the error count.
err_guars: Vec<ErrorGuaranteed>,
/// The error guarantee from all emitted lint errors. The length gives the
@ -480,11 +476,6 @@ impl DiagCtxt {
self
}
pub fn with_registry(mut self, registry: Registry) -> Self {
self.inner.get_mut().registry = registry;
self
}
pub fn new(emitter: Box<DynEmitter>) -> Self {
Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
}
@ -537,7 +528,6 @@ impl DiagCtxt {
let mut inner = self.inner.borrow_mut();
let DiagCtxtInner {
flags: _,
registry: _,
err_guars,
lint_err_guars,
delayed_bugs,
@ -811,7 +801,7 @@ impl<'a> DiagCtxtHandle<'a> {
.emitted_diagnostic_codes
.iter()
.filter_map(|&code| {
if inner.registry.try_find_description(code).is_ok() {
if crate::codes::try_find_description(code).is_ok() {
Some(code.to_string())
} else {
None
@ -883,7 +873,7 @@ impl<'a> DiagCtxtHandle<'a> {
let inner = &mut *self.inner.borrow_mut();
let diags = std::mem::take(&mut inner.future_breakage_diagnostics);
if !diags.is_empty() {
inner.emitter.emit_future_breakage_report(diags, &inner.registry);
inner.emitter.emit_future_breakage_report(diags);
}
}
@ -1184,7 +1174,6 @@ impl DiagCtxtInner {
fn new(emitter: Box<DynEmitter>) -> Self {
Self {
flags: DiagCtxtFlags { can_emit_warnings: true, ..Default::default() },
registry: Registry::new(&[]),
err_guars: Vec::new(),
lint_err_guars: Vec::new(),
delayed_bugs: Vec::new(),
@ -1360,7 +1349,7 @@ impl DiagCtxtInner {
}
self.has_printed = true;
self.emitter.emit_diagnostic(diagnostic, &self.registry);
self.emitter.emit_diagnostic(diagnostic);
}
if is_error {

View file

@ -1,23 +0,0 @@
use rustc_data_structures::fx::FxHashMap;
use crate::ErrCode;
#[derive(Debug)]
pub struct InvalidErrorCode;
#[derive(Clone)]
pub struct Registry {
long_descriptions: FxHashMap<ErrCode, &'static str>,
}
impl Registry {
pub fn new(long_descriptions: &[(ErrCode, &'static str)]) -> Registry {
Registry { long_descriptions: long_descriptions.iter().copied().collect() }
}
/// Returns `InvalidErrorCode` if the code requested does not exist in the
/// registry.
pub fn try_find_description(&self, code: ErrCode) -> Result<&'static str, InvalidErrorCode> {
self.long_descriptions.get(&code).copied().ok_or(InvalidErrorCode)
}
}

View file

@ -3,8 +3,8 @@ use std::env;
use std::error::Report;
use std::sync::Arc;
use rustc_error_messages::langid;
pub use rustc_error_messages::{FluentArgs, LazyFallbackBundle};
use rustc_error_messages::{langid, register_functions};
use tracing::{debug, trace};
use crate::error::{TranslateError, TranslateErrorKind};
@ -91,6 +91,7 @@ impl Translator {
let mut bundle = fluent_bundle::FluentBundle::new(vec![langid!("en-US")]);
bundle.set_use_isolating(false);
bundle.add_resource(resource).unwrap();
register_functions(&mut bundle);
let message = bundle.get_message(GENERATED_MSG_ID).unwrap();
let value = message.value().unwrap();

View file

@ -167,6 +167,14 @@ pub enum CoverageAttrKind {
Off,
}
/// Successfully-parsed value of a `#[rustc_abi(..)]` attribute.
#[derive(Copy, Debug, Eq, PartialEq, Encodable, Decodable, Clone)]
#[derive(HashStable_Generic, PrintAttribute)]
pub enum RustcAbiAttrKind {
Debug,
AssertEq,
}
impl Deprecation {
/// Whether an item marked with #[deprecated(since = "X")] is currently
/// deprecated (i.e., whether X is not greater than the current rustc
@ -1015,6 +1023,9 @@ pub enum AttributeKind {
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
Repr { reprs: ThinVec<(ReprAttr, Span)>, first_span: Span },
/// Represents `#[rustc_abi(..)]`
RustcAbi { attr_span: Span, kind: RustcAbiAttrKind },
/// Represents `#[rustc_allocator]`
RustcAllocator,
@ -1094,6 +1105,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_dyn_incompatible_trait]`.
RustcDynIncompatibleTrait(Span),
/// Represents `#[rustc_effective_visibility]`.
RustcEffectiveVisibility,
/// Represents `#[rustc_has_incoherent_inherent_impls]`
RustcHasIncoherentInherentImpls,

View file

@ -89,6 +89,7 @@ impl AttributeKind {
RecursionLimit { .. } => No,
ReexportTestHarnessMain(..) => No,
Repr { .. } => No,
RustcAbi { .. } => No,
RustcAllocator => No,
RustcAllocatorZeroed => No,
RustcAllocatorZeroedVariant { .. } => Yes,
@ -112,6 +113,7 @@ impl AttributeKind {
RustcDumpUserArgs => No,
RustcDumpVtable(..) => No,
RustcDynIncompatibleTrait(..) => No,
RustcEffectiveVisibility => Yes,
RustcHasIncoherentInherentImpls => Yes,
RustcHiddenTypeOfOpaques => No,
RustcIfThisChanged(..) => No,

View file

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

View file

@ -1,606 +0,0 @@
hir_analysis_abi_custom_clothed_function =
items with the "custom" ABI can only be declared externally or defined via naked functions
.suggestion = convert this to an `#[unsafe(naked)]` function
hir_analysis_ambiguous_assoc_item = ambiguous associated {$assoc_kind} `{$assoc_ident}` in bounds of `{$qself}`
.label = ambiguous associated {$assoc_kind} `{$assoc_ident}`
hir_analysis_ambiguous_lifetime_bound =
ambiguous lifetime bound, explicit lifetime bound required
hir_analysis_assoc_item_constraints_not_allowed_here =
associated item constraints are not allowed here
.label = associated item constraint not allowed here
hir_analysis_assoc_item_is_private = {$kind} `{$name}` is private
.label = private {$kind}
.defined_here_label = the {$kind} is defined here
hir_analysis_assoc_item_not_found = associated {$assoc_kind} `{$assoc_ident}` not found for `{$qself}`
hir_analysis_assoc_item_not_found_found_in_other_trait_label = there is {$identically_named ->
[true] an
*[false] a similarly named
} associated {$assoc_kind} `{$suggested_name}` in the trait `{$trait_name}`
hir_analysis_assoc_item_not_found_label = associated {$assoc_kind} `{$assoc_ident}` not found
hir_analysis_assoc_item_not_found_other_sugg = `{$qself}` has the following associated {$assoc_kind}
hir_analysis_assoc_item_not_found_similar_in_other_trait_qpath_sugg =
consider fully qualifying{$identically_named ->
[true] {""}
*[false] {" "}and renaming
} the associated {$assoc_kind}
hir_analysis_assoc_item_not_found_similar_in_other_trait_sugg = change the associated {$assoc_kind} name to use `{$suggested_name}` from `{$trait_name}`
hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg = ...and changing the associated {$assoc_kind} name
hir_analysis_assoc_item_not_found_similar_sugg = there is an associated {$assoc_kind} with a similar name
hir_analysis_assoc_kind_mismatch = expected {$expected}, found {$got}
.label = unexpected {$got}
.expected_because_label = expected a {$expected} because of this associated {$expected}
.note = the associated {$assoc_kind} is defined here
.bound_on_assoc_const_label = bounds are not allowed on associated constants
hir_analysis_assoc_kind_mismatch_wrap_in_braces_sugg = consider adding braces here
hir_analysis_associated_type_trait_uninferred_generic_params = cannot use the {$what} of a trait with uninferred generic parameters
.suggestion = use a fully qualified path with inferred lifetimes
hir_analysis_associated_type_trait_uninferred_generic_params_multipart_suggestion = use a fully qualified path with explicit lifetimes
hir_analysis_async_drop_without_sync_drop = `AsyncDrop` impl without `Drop` impl
.help = type implementing `AsyncDrop` trait must also implement `Drop` trait to be used in sync context and unwinds
hir_analysis_auto_deref_reached_recursion_limit = reached the recursion limit while auto-dereferencing `{$ty}`
.label = deref recursion limit reached
.help = consider increasing the recursion limit by adding a `#![recursion_limit = "{$suggested_limit}"]` attribute to your crate (`{$crate_name}`)
hir_analysis_bad_precise_capture = expected {$kind} parameter in `use<...>` precise captures list, found {$found}
hir_analysis_bad_return_type_notation_position = return type notation not allowed in this position yet
hir_analysis_cannot_capture_late_bound_const =
cannot capture late-bound const parameter in {$what}
.label = parameter defined here
hir_analysis_cannot_capture_late_bound_lifetime =
cannot capture late-bound lifetime in {$what}
.label = lifetime defined here
hir_analysis_cannot_capture_late_bound_ty =
cannot capture late-bound type parameter in {$what}
.label = parameter defined here
hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present
.label = `for<...>` is here
hir_analysis_cmse_generic =
generics are not allowed in `extern {$abi}` signatures
hir_analysis_cmse_impl_trait =
`impl Trait` is not allowed in `extern {$abi}` signatures
hir_analysis_cmse_inputs_stack_spill =
arguments for `{$abi}` function too large to pass via registers
.label = does not fit in the available registers
.note = functions with the `{$abi}` ABI must pass all their arguments via the 4 32-bit argument registers
hir_analysis_cmse_output_stack_spill =
return value of `{$abi}` function too large to pass via registers
.label = this type doesn't fit in the available registers
.note1 = functions with the `{$abi}` ABI must pass their result via the available return registers
.note2 = the result must either be a (transparently wrapped) i64, u64 or f64, or be at most 4 bytes in size
hir_analysis_coerce_multi = implementing `{$trait_name}` does not allow multiple fields to be coerced
.note = the trait `{$trait_name}` may only be implemented when a single field is being coerced
.label = these fields must be coerced for `{$trait_name}` to be valid
hir_analysis_coerce_pointee_no_field = `CoercePointee` can only be derived on `struct`s with at least one field
hir_analysis_coerce_pointee_no_user_validity_assertion = asserting applicability of `derive(CoercePointee)` on a target data is forbidden
hir_analysis_coerce_pointee_not_concrete_ty = `derive(CoercePointee)` is only applicable to `struct`
hir_analysis_coerce_pointee_not_struct = `derive(CoercePointee)` is only applicable to `struct`, instead of `{$kind}`
hir_analysis_coerce_pointee_not_transparent = `derive(CoercePointee)` is only applicable to `struct` with `repr(transparent)` layout
hir_analysis_coerce_same_pat_kind = only pattern types with the same pattern can be coerced between each other
hir_analysis_coerce_unsized_field_validity = for `{$ty}` to have a valid implementation of `{$trait_name}`, it must be possible to coerce the field of type `{$field_ty}`
.label = `{$field_ty}` must be a pointer, reference, or smart pointer that is allowed to be unsized
hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
hir_analysis_coerce_zero = implementing `{$trait_name}` requires a field to be coerced
hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}`
hir_analysis_coercion_between_struct_single_note = expected a single field to be coerced, none found
hir_analysis_const_bound_for_non_const_trait = `{$modifier}` can only be applied to `const` traits
.label = can't be applied to `{$trait_name}`
.note = `{$trait_name}` can't be used with `{$modifier}` because it isn't `const`
.suggestion = {$suggestion_pre}mark `{$trait_name}` as `const` to allow it to have `const` implementations
hir_analysis_const_impl_for_non_const_trait = const `impl` for trait `{$trait_name}` which is not `const`
.label = this trait is not `const`
.suggestion = {$suggestion_pre}mark `{$trait_name}` as `const` to allow it to have `const` implementations
.note = marking a trait with `const` ensures all default method bodies are `const`
.adding = adding a non-const method body in the future would be a breaking change
hir_analysis_const_param_ty_impl_on_non_adt =
the trait `ConstParamTy` may not be implemented for this type
.label = type is not a structure or enumeration
hir_analysis_const_param_ty_impl_on_unsized =
the trait `ConstParamTy` may not be implemented for this type
.label = type is not `Sized`
hir_analysis_copy_impl_on_non_adt =
the trait `Copy` cannot be implemented for this type
.label = type is not a structure or enumeration
hir_analysis_copy_impl_on_type_with_dtor =
the trait `Copy` cannot be implemented for this type; the type has a destructor
.label = `Copy` not allowed on types with destructors
.note = destructor declared here
hir_analysis_cross_crate_traits = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type, not `{$self_ty}`
.label = can't implement cross-crate trait with a default impl for non-struct/enum type
hir_analysis_cross_crate_traits_defined = cross-crate traits with a default impl, like `{$traits}`, can only be implemented for a struct/enum type defined in the current crate
.label = can't implement cross-crate trait for type in another crate
hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment that don't mention type/const generics, and nothing else
.note = extra field `{$name}` of type `{$ty}` is not allowed
hir_analysis_drop_impl_negative = negative `Drop` impls are not supported
hir_analysis_drop_impl_on_wrong_item =
the `{$trait_}` trait may only be implemented for local structs, enums, and unions
.label = must be a struct, enum, or union in the current crate
hir_analysis_drop_impl_reservation = reservation `Drop` impls are not supported
hir_analysis_duplicate_precise_capture = cannot capture parameter `{$name}` twice
.label = parameter captured again here
hir_analysis_dyn_trait_assoc_item_binding_mentions_self =
{$kind} binding in trait object type mentions `Self`
.label = contains a mention of `Self`
.binding_label = this binding mentions `Self`
hir_analysis_eii_with_generics =
`{$impl_name}` cannot have generic parameters other than lifetimes
.label = required by this attribute
.help = `#[{$eii_name}]` marks the implementation of an "externally implementable item"
hir_analysis_empty_specialization = specialization impl does not specialize any associated items
.note = impl is a specialization of this impl
hir_analysis_enum_discriminant_overflowed = enum discriminant overflowed
.label = overflowed on value after {$discr}
.note = explicitly set `{$item_name} = {$wrapped_discr}` if that is desired outcome
hir_analysis_escaping_bound_var_in_ty_of_assoc_const_binding =
the type of the associated constant `{$assoc_const}` cannot capture late-bound generic parameters
.label = its type cannot capture the late-bound {$var_def_kind} `{$var_name}`
.var_defined_here_label = the late-bound {$var_def_kind} `{$var_name}` is defined here
hir_analysis_field_already_declared =
field `{$field_name}` is already declared
.label = field already declared
.previous_decl_label = `{$field_name}` first declared here
hir_analysis_field_already_declared_both_nested =
field `{$field_name}` is already declared
.label = field `{$field_name}` declared in this unnamed field
.nested_field_decl_note = field `{$field_name}` declared here
.previous_decl_label = `{$field_name}` first declared here in this unnamed field
.previous_nested_field_decl_note = field `{$field_name}` first declared here
hir_analysis_field_already_declared_current_nested =
field `{$field_name}` is already declared
.label = field `{$field_name}` declared in this unnamed field
.nested_field_decl_note = field `{$field_name}` declared here
.previous_decl_label = `{$field_name}` first declared here
hir_analysis_field_already_declared_nested_help =
fields from the type of this unnamed field are considered fields of the outer type
hir_analysis_field_already_declared_previous_nested =
field `{$field_name}` is already declared
.label = field already declared
.previous_decl_label = `{$field_name}` first declared here in this unnamed field
.previous_nested_field_decl_note = field `{$field_name}` first declared here
hir_analysis_generic_args_on_overridden_impl = could not resolve generic parameters on overridden impl
hir_analysis_impl_not_marked_default = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
.label = cannot specialize default item `{$ident}`
.ok_label = parent `impl` is here
.note = to specialize, `{$ident}` in the parent `impl` must be marked `default`
hir_analysis_impl_not_marked_default_err = `{$ident}` specializes an item from a parent `impl`, but that item is not marked `default`
.note = parent implementation is in crate `{$cname}`
hir_analysis_impl_unpin_for_pin_projected_type = explicit impls for the `Unpin` trait are not permitted for structurally pinned types
.label = impl of `Unpin` not allowed
.help = `{$adt_name}` is structurally pinned because it is marked as `#[pin_v2]`
hir_analysis_inherent_dyn = cannot define inherent `impl` for a dyn auto trait
.label = impl requires at least one non-auto trait
.note = define and implement a new trait or type instead
hir_analysis_inherent_nominal = no nominal type found for inherent implementation
.label = impl requires a nominal type
.note = either implement a trait on it or create a newtype to wrap it instead
hir_analysis_inherent_primitive_ty = cannot define inherent `impl` for primitive types
.help = consider using an extension trait instead
hir_analysis_inherent_primitive_ty_note = you could also try moving the reference to uses of `{$subty}` (such as `self`) within the implementation
hir_analysis_inherent_ty_outside = cannot define inherent `impl` for a type outside of the crate where the type is defined
.help = consider moving this inherent impl into the crate defining the type if possible
.span_help = alternatively add `#[rustc_has_incoherent_inherent_impls]` to the type and `#[rustc_allow_incoherent_impl]` to the relevant impl items
hir_analysis_inherent_ty_outside_new = cannot define inherent `impl` for a type outside of the crate where the type is defined
.label = impl for type defined outside of crate
.note = define and implement a trait or new type instead
hir_analysis_inherent_ty_outside_primitive = cannot define inherent `impl` for primitive types outside of `core`
.help = consider moving this inherent impl into `core` if possible
.span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a type outside of the crate where the type is defined
.help = consider moving this inherent impl into the crate defining the type if possible
.span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
.note = type of `self` must not be a method generic parameter type
hir_analysis_invalid_generic_receiver_ty_help =
use a concrete type such as `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
hir_analysis_invalid_receiver_ty = invalid `self` parameter type: `{$receiver_ty}`
.note = type of `self` must be `Self` or some type implementing `Receiver`
hir_analysis_invalid_receiver_ty_help =
consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`
hir_analysis_invalid_receiver_ty_help_no_arbitrary_self_types =
consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
hir_analysis_invalid_receiver_ty_help_nonnull_note =
`NonNull` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `NonNull` in a newtype wrapper for which you implement `Receiver`
hir_analysis_invalid_receiver_ty_help_weak_note =
`Weak` does not implement `Receiver` because it has methods that may shadow the referent; consider wrapping your `Weak` in a newtype wrapper for which you implement `Receiver`
hir_analysis_invalid_receiver_ty_no_arbitrary_self_types = invalid `self` parameter type: `{$receiver_ty}`
.note = type of `self` must be `Self` or a type that dereferences to it
hir_analysis_invalid_union_field =
field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
.note = union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
hir_analysis_invalid_union_field_sugg =
wrap the field type in `ManuallyDrop<...>`
hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
.label = const parameter declared here
hir_analysis_late_bound_lifetime_in_apit = `impl Trait` can only mention lifetimes from an fn or impl
.label = lifetime declared here
hir_analysis_late_bound_type_in_apit = `impl Trait` can only mention type parameters from an fn or impl
.label = type parameter declared here
hir_analysis_lifetime_implicitly_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
.param_label = all lifetime parameters originating from a trait are captured implicitly
hir_analysis_lifetime_must_be_first = lifetime parameter `{$name}` must be listed before non-lifetime parameters
.label = move the lifetime before this parameter
hir_analysis_lifetime_not_captured = `impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list
.label = lifetime captured due to being mentioned in the bounds of the `impl Trait`
.param_label = this lifetime parameter is captured
hir_analysis_lifetimes_or_bounds_mismatch_on_eii =
lifetime parameters or bounds of `{$ident}` do not match the declaration
.label = lifetimes do not match
.generics_label = lifetimes in impl do not match this signature
.where_label = this `where` clause might not match the one in the declaration
.bounds_label = this bound might be missing in the implementation
hir_analysis_lifetimes_or_bounds_mismatch_on_trait =
lifetime parameters or bounds on {$item_kind} `{$ident}` do not match the trait declaration
.label = lifetimes do not match {$item_kind} in trait
.generics_label = lifetimes in impl do not match this {$item_kind} in trait
.where_label = this `where` clause might not match the one in the trait
.bounds_label = this bound might be missing in the impl
hir_analysis_linkage_type =
invalid type for variable with `#[linkage]` attribute
hir_analysis_main_function_async = `main` function is not allowed to be `async`
.label = `main` function is not allowed to be `async`
hir_analysis_main_function_generic_parameters = `main` function is not allowed to have generic parameters
.label = `main` cannot have generic parameters
hir_analysis_main_function_return_type_generic = `main` function return type is not allowed to have generic parameters
hir_analysis_manual_implementation =
manual implementations of `{$trait_name}` are experimental
.label = manual implementations of `{$trait_name}` are experimental
.help = add `#![feature(unboxed_closures)]` to the crate attributes to enable
hir_analysis_method_should_return_future = method should be `async` or return a future, but it is synchronous
.note = this method is `async` so it expects a future to be returned
hir_analysis_missing_generic_params =
the {$descr} {$parameterCount ->
[one] parameter
*[other] parameters
} {$parameters} must be explicitly specified
.label = {$descr} {$parameterCount ->
[one] parameter
*[other] parameters
} {$parameters} must be specified for this
.suggestion = explicitly specify the {$descr} {$parameterCount ->
[one] parameter
*[other] parameters
}
.no_suggestion_label = missing {$parameterCount ->
[one] reference
*[other] references
} to {$parameters}
.note = because the parameter {$parameterCount ->
[one] default references
*[other] defaults reference
} `Self`, the {$parameterCount ->
[one] parameter
*[other] parameters
} must be specified on the trait object type
hir_analysis_missing_one_of_trait_item = not all trait items implemented, missing one of: `{$missing_items_msg}`
.label = missing one of `{$missing_items_msg}` in implementation
.note = required because of this annotation
hir_analysis_missing_trait_item = not all trait items implemented, missing: `{$missing_items_msg}`
.label = missing `{$missing_items_msg}` in implementation
hir_analysis_missing_trait_item_label = `{$item}` from trait
hir_analysis_missing_trait_item_suggestion = implement the missing item: `{$snippet}`
hir_analysis_missing_trait_item_unstable = not all trait items implemented, missing: `{$missing_item_name}`
.note = default implementation of `{$missing_item_name}` is unstable
.some_note = use of unstable library feature `{$feature}`: {$reason}
.none_note = use of unstable library feature `{$feature}`
hir_analysis_no_variant_named = no variant named `{$ident}` found for enum `{$ty}`
hir_analysis_not_supported_delegation = {$descr}
.label = callee defined here
hir_analysis_only_current_traits_adt = `{$name}` is not defined in the current crate
hir_analysis_only_current_traits_arbitrary = only traits defined in the current crate can be implemented for arbitrary types
hir_analysis_only_current_traits_foreign = this is not defined in the current crate because this is a foreign trait
hir_analysis_only_current_traits_name = this is not defined in the current crate because {$name} are always foreign
hir_analysis_only_current_traits_note = define and implement a trait or new type instead
hir_analysis_only_current_traits_note_more_info = for more information see https://doc.rust-lang.org/reference/items/implementations.html#orphan-rules
hir_analysis_only_current_traits_note_uncovered = impl doesn't have any local type before any uncovered type parameters
hir_analysis_only_current_traits_opaque = type alias impl trait is treated as if it were foreign, because its hidden type could be from a foreign crate
hir_analysis_only_current_traits_outside = only traits defined in the current crate can be implemented for types defined outside of the crate
hir_analysis_only_current_traits_pointer = `{$pointer}` is not defined in the current crate because raw pointers are always foreign
hir_analysis_only_current_traits_pointer_sugg = consider introducing a new wrapper type
hir_analysis_only_current_traits_primitive = only traits defined in the current crate can be implemented for primitive types
hir_analysis_only_current_traits_ty = `{$ty}` is not defined in the current crate
hir_analysis_opaque_captures_higher_ranked_lifetime = `impl Trait` cannot capture {$bad_place}
.label = `impl Trait` implicitly captures all lifetimes in scope
.note = lifetime declared here
hir_analysis_param_in_ty_of_assoc_const_binding =
the type of the associated constant `{$assoc_const}` must not depend on {$param_category ->
[self] `Self`
[synthetic] `impl Trait`
*[normal] generic parameters
}
.label = its type must not depend on {$param_category ->
[self] `Self`
[synthetic] `impl Trait`
*[normal] the {$param_def_kind} `{$param_name}`
}
.param_defined_here_label = {$param_category ->
[synthetic] the `impl Trait` is specified here
*[normal] the {$param_def_kind} `{$param_name}` is defined here
}
hir_analysis_param_not_captured = `impl Trait` must mention all {$kind} parameters in scope in `use<...>`
.label = {$kind} parameter is implicitly captured by this `impl Trait`
.note = currently, all {$kind} parameters are required to be mentioned in the precise captures list
hir_analysis_paren_sugar_attribute = the `#[rustc_paren_sugar]` attribute is a temporary means of controlling which traits can use parenthetical notation
.help = add `#![feature(unboxed_closures)]` to the crate attributes to use it
hir_analysis_parenthesized_fn_trait_expansion =
parenthesized trait syntax expands to `{$expanded_type}`
hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
.label = not allowed in type signatures
hir_analysis_precise_capture_self_alias = `Self` can't be captured in `use<...>` precise captures list, since it is an alias
.label = `Self` is not a generic argument, but an alias to the type of the {$what}
hir_analysis_recursive_generic_parameter = {$param_def_kind} `{$param_name}` is only used recursively
.label = {$param_def_kind} must be used non-recursively in the definition
.note = all type parameters must be used in a non-recursive way in order to constrain their variance
hir_analysis_redundant_lifetime_args = unnecessary lifetime parameter `{$victim}`
.note = you can use the `{$candidate}` lifetime directly, in place of `{$victim}`
hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`
hir_analysis_return_type_notation_equality_bound =
return type notation is not allowed to use type equality
hir_analysis_return_type_notation_illegal_param_const =
return type notation is not allowed for functions that have const parameters
.label = const parameter declared here
hir_analysis_return_type_notation_illegal_param_type =
return type notation is not allowed for functions that have type parameters
.label = type parameter declared here
hir_analysis_return_type_notation_on_non_rpitit =
return type notation used on function that is not `async` and does not return `impl Trait`
.note = function returns `{$ty}`, which is not compatible with associated type return bounds
.label = this function must be `async` or return `impl Trait`
hir_analysis_rpitit_refined = impl trait in impl method signature does not match trait method signature
.suggestion = replace the return type so that it matches the trait
.label = return type from trait method defined here
.unmatched_bound_label = this bound is stronger than that defined on the trait
.note = add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
.feedback_note = we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
hir_analysis_rpitit_refined_lifetimes = impl trait in impl method captures fewer lifetimes than in trait
.suggestion = modify the `use<..>` bound to capture the same lifetimes that the trait does
.note = add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
.feedback_note = we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
hir_analysis_self_in_impl_self =
`Self` is not valid in the self type of an impl block
.note = replace `Self` with a different type
hir_analysis_self_ty_not_captured = `impl Trait` must mention the `Self` type of the trait in `use<...>`
.label = `Self` type parameter is implicitly captured by this `impl Trait`
.note = currently, all type parameters are required to be mentioned in the precise captures list
hir_analysis_simd_ffi_highly_experimental = use of SIMD type{$snip} in FFI is highly experimental and may result in invalid code
.help = add `#![feature(simd_ffi)]` to the crate attributes to enable
hir_analysis_specialization_trait = implementing `rustc_specialization_trait` traits is unstable
.help = add `#![feature(min_specialization)]` to the crate attributes to enable
hir_analysis_static_specialize = cannot specialize on `'static` lifetime
hir_analysis_supertrait_item_multiple_shadowee = items from several supertraits are shadowed: {$traits}
hir_analysis_supertrait_item_shadowee = item from `{$supertrait}` is shadowed by a subtrait item
hir_analysis_supertrait_item_shadowing = trait item `{$item}` from `{$subtrait}` shadows identically named item from supertrait
hir_analysis_target_feature_on_main = `main` function is not allowed to have `#[target_feature]`
hir_analysis_too_large_static = extern static is too large for the target architecture
hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]`
.suggestion = remove this annotation
hir_analysis_trait_cannot_impl_for_ty = the trait `{$trait_name}` cannot be implemented for this type
.label = this field does not implement `{$trait_name}`
hir_analysis_trait_object_declared_with_no_traits =
at least one trait is required for an object type
.alias_span = this alias does not contain a trait
hir_analysis_traits_with_default_impl = traits with a default impl, like `{$traits}`, cannot be implemented for {$problematic_kind} `{$self_ty}`
.note = a trait object implements `{$traits}` if and only if `{$traits}` is one of the trait object's trait bounds
hir_analysis_transparent_enum_variant = transparent enum needs exactly one variant, but has {$number}
.label = needs exactly one variant, but has {$number}
.many_label = too many variants in `{$path}`
.multi_label = variant here
hir_analysis_transparent_non_zero_sized = transparent {$desc} needs at most one field with non-trivial size or alignment, but has {$field_count}
.label = needs at most one field with non-trivial size or alignment, but has {$field_count}
.labels = this field has non-zero size or requires alignment
hir_analysis_transparent_non_zero_sized_enum = the variant of a transparent {$desc} needs at most one field with non-trivial size or alignment, but has {$field_count}
.label = needs at most one field with non-trivial size or alignment, but has {$field_count}
.labels = this field has non-zero size or requires alignment
hir_analysis_ty_of_assoc_const_binding_note = `{$assoc_const}` has type `{$ty}`
hir_analysis_ty_param_first_local = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`)
.label = type parameter `{$param}` must be covered by another type when it appears before the first local type (`{$local_type}`)
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
.case_note = in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
hir_analysis_ty_param_some = type parameter `{$param}` must be used as the type parameter for some local type (e.g., `MyStruct<{$param}>`)
.label = type parameter `{$param}` must be used as the type parameter for some local type
.note = implementing a foreign trait is only possible if at least one of the types for which it is implemented is local
.only_note = only traits defined in the current crate can be implemented for a type parameter
hir_analysis_type_of = {$ty}
hir_analysis_unconstrained_generic_parameter = the {$param_def_kind} `{$param_name}` is not constrained by the impl trait, self type, or predicates
.label = unconstrained {$param_def_kind}
.const_param_note = expressions using a const parameter must map each value to a distinct output value
.const_param_note2 = proving the result of expressions other than the parameter are unique is not supported
hir_analysis_unconstrained_opaque_type = unconstrained opaque type
.note = `{$name}` must be used in combination with a concrete type within the same {$what}
hir_analysis_unrecognized_intrinsic_function =
unrecognized intrinsic function: `{$name}`
.label = unrecognized intrinsic
.help = if you're adding an intrinsic, be sure to update `check_intrinsic_type`
hir_analysis_unused_associated_type_bounds =
unnecessary associated type bound for dyn-incompatible associated type
.note = this associated type has a `where Self: Sized` bound, and while the associated type can be specified, it cannot be used because trait objects are never `Sized`
.suggestion = remove this bound
hir_analysis_unused_generic_parameter =
{$param_def_kind} `{$param_name}` is never used
.label = unused {$param_def_kind}
.const_param_help = if you intended `{$param_name}` to be a const parameter, use `const {$param_name}: /* Type */` instead
.usage_spans = `{$param_name}` is named here, but is likely unused in the containing type
hir_analysis_unused_generic_parameter_adt_help =
consider removing `{$param_name}`, referring to it in a field, or using a marker such as `{$phantom_data}`
hir_analysis_unused_generic_parameter_adt_no_phantom_data_help =
consider removing `{$param_name}` or referring to it in a field
hir_analysis_unused_generic_parameter_ty_alias_help =
consider removing `{$param_name}` or referring to it in the body of the type alias
hir_analysis_useless_impl_item = this item cannot be used as its where bounds are not satisfied for the `Self` type
hir_analysis_value_of_associated_struct_already_specified =
the value of the associated type `{$item_name}` in trait `{$def_path}` is already specified
.label = re-bound here
.previous_bound_label = `{$item_name}` bound here first
hir_analysis_variadic_function_compatible_convention = C-variadic functions with the {$convention} calling convention are not supported
.label = C-variadic function must have a compatible calling convention
hir_analysis_variances_of = {$variances}
hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause
.label = `main` cannot have a `where` clause
hir_analysis_within_macro = due to this macro variable
hir_analysis_wrong_number_of_generic_arguments_to_intrinsic =
intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
.label = expected {$expected} {$descr} {$expected ->
[one] parameter
*[other] parameters
}

View file

@ -923,7 +923,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
);
check_where_clauses(wfcx, def_id);
if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
if tcx.is_type_const(def_id.into()) {
wfcheck::check_type_const(wfcx, def_id, ty, true)?;
}
Ok(())

View file

@ -6,10 +6,9 @@ use hir::def_id::{DefId, DefIdMap, LocalDefId};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan, pluralize, struct_span_code_err};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::VisitorExt;
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, find_attr, intravisit};
use rustc_hir::{self as hir, AmbigArg, GenericParamKind, ImplItemKind, intravisit};
use rustc_infer::infer::{self, BoundRegionConversionTime, InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::util;
use rustc_middle::ty::error::{ExpectedFound, TypeError};
@ -2051,12 +2050,8 @@ fn compare_type_const<'tcx>(
impl_const_item: ty::AssocItem,
trait_const_item: ty::AssocItem,
) -> Result<(), ErrorGuaranteed> {
let impl_is_type_const =
find_attr!(tcx.get_all_attrs(impl_const_item.def_id), AttributeKind::TypeConst(_));
let trait_type_const_span = find_attr!(
tcx.get_all_attrs(trait_const_item.def_id),
AttributeKind::TypeConst(sp) => *sp
);
let impl_is_type_const = tcx.is_type_const(impl_const_item.def_id);
let trait_type_const_span = tcx.type_const_span(trait_const_item.def_id);
if let Some(trait_type_const_span) = trait_type_const_span
&& !impl_is_type_const

View file

@ -5,7 +5,9 @@ use hir::intravisit::{self, Visitor};
use rustc_abi::{ExternAbi, ScalableElt};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::{Applicability, ErrorGuaranteed, pluralize, struct_span_code_err};
use rustc_errors::{
Applicability, ErrorGuaranteed, inline_fluent, pluralize, struct_span_code_err,
};
use rustc_hir::attrs::{AttributeKind, EiiDecl, EiiImpl, EiiImplResolution};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
@ -42,8 +44,8 @@ use {rustc_ast as ast, rustc_hir as hir};
use super::compare_eii::compare_eii_function_types;
use crate::autoderef::Autoderef;
use crate::constrained_generic_params::{Parameter, identify_constrained_generic_params};
use crate::errors;
use crate::errors::InvalidReceiverTyHint;
use crate::{errors, fluent_generated as fluent};
pub(super) struct WfCheckingCtxt<'a, 'tcx> {
pub(super) ocx: ObligationCtxt<'a, 'tcx, FulfillmentError<'tcx>>,
@ -953,7 +955,7 @@ pub(crate) fn check_associated_item(
wfcx.register_wf_obligation(span, loc, ty.into());
let has_value = item.defaultness(tcx).has_value();
if find_attr!(tcx.get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
if tcx.is_type_const(def_id.into()) {
check_type_const(wfcx, def_id, ty, has_value)?;
}
@ -1740,7 +1742,7 @@ fn check_method_receiver<'tcx>(
the `arbitrary_self_types` feature",
),
)
.with_help(fluent::hir_analysis_invalid_receiver_ty_help)
.with_help(inline_fluent!("consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`"))
.emit()
}
None | Some(ArbitrarySelfTypesLevel::Basic)
@ -1764,7 +1766,7 @@ fn check_method_receiver<'tcx>(
the `arbitrary_self_types_pointers` feature",
),
)
.with_help(fluent::hir_analysis_invalid_receiver_ty_help)
.with_help(inline_fluent!("consider changing to `self`, `&self`, `&mut self`, or a type implementing `Receiver` such as `self: Box<Self>`, `self: Rc<Self>`, or `self: Arc<Self>`"))
.emit()
}
_ =>
@ -2442,8 +2444,8 @@ fn lint_redundant_lifetimes<'tcx>(
}
#[derive(LintDiagnostic)]
#[diag(hir_analysis_redundant_lifetime_args)]
#[note]
#[diag("unnecessary lifetime parameter `{$victim}`")]
#[note("you can use the `{$candidate}` lifetime directly, in place of `{$victim}`")]
struct RedundantLifetimeArgsLint<'tcx> {
/// The lifetime we have found to be redundant.
victim: ty::Region<'tcx>,

File diff suppressed because it is too large Load diff

View file

@ -3,48 +3,54 @@ use rustc_macros::Diagnostic;
use rustc_span::{Span, Symbol};
#[derive(Diagnostic)]
#[diag(hir_analysis_param_not_captured)]
#[note]
#[diag("`impl Trait` must mention all {$kind} parameters in scope in `use<...>`")]
#[note(
"currently, all {$kind} parameters are required to be mentioned in the precise captures list"
)]
pub(crate) struct ParamNotCaptured {
#[primary_span]
pub opaque_span: Span,
#[label]
#[label("{$kind} parameter is implicitly captured by this `impl Trait`")]
pub param_span: Span,
pub kind: &'static str,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_self_ty_not_captured)]
#[note]
#[diag("`impl Trait` must mention the `Self` type of the trait in `use<...>`")]
#[note("currently, all type parameters are required to be mentioned in the precise captures list")]
pub(crate) struct SelfTyNotCaptured {
#[primary_span]
pub opaque_span: Span,
#[label]
#[label("`Self` type parameter is implicitly captured by this `impl Trait`")]
pub trait_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_lifetime_not_captured)]
#[diag(
"`impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list"
)]
pub(crate) struct LifetimeNotCaptured {
#[primary_span]
pub use_span: Span,
#[label(hir_analysis_param_label)]
#[label("this lifetime parameter is captured")]
pub param_span: Span,
#[label]
#[label("lifetime captured due to being mentioned in the bounds of the `impl Trait`")]
pub opaque_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_lifetime_implicitly_captured)]
#[diag(
"`impl Trait` captures lifetime parameter, but it is not mentioned in `use<...>` precise captures list"
)]
pub(crate) struct LifetimeImplicitlyCaptured {
#[primary_span]
pub opaque_span: Span,
#[label(hir_analysis_param_label)]
#[label("all lifetime parameters originating from a trait are captured implicitly")]
pub param_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_bad_precise_capture)]
#[diag("expected {$kind} parameter in `use<...>` precise captures list, found {$found}")]
pub(crate) struct BadPreciseCapture {
#[primary_span]
pub span: Span,
@ -53,31 +59,31 @@ pub(crate) struct BadPreciseCapture {
}
#[derive(Diagnostic)]
#[diag(hir_analysis_precise_capture_self_alias, code = E0799)]
#[diag("`Self` can't be captured in `use<...>` precise captures list, since it is an alias", code = E0799)]
pub(crate) struct PreciseCaptureSelfAlias {
#[primary_span]
pub span: Span,
#[label]
#[label("`Self` is not a generic argument, but an alias to the type of the {$what}")]
pub self_span: Span,
pub what: &'static str,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_duplicate_precise_capture)]
#[diag("cannot capture parameter `{$name}` twice")]
pub(crate) struct DuplicatePreciseCapture {
#[primary_span]
pub first_span: Span,
pub name: Symbol,
#[label]
#[label("parameter captured again here")]
pub second_span: Span,
}
#[derive(Diagnostic)]
#[diag(hir_analysis_lifetime_must_be_first)]
#[diag("lifetime parameter `{$name}` must be listed before non-lifetime parameters")]
pub(crate) struct LifetimesMustBeFirst {
#[primary_span]
pub lifetime_span: Span,
pub name: Symbol,
#[label]
#[label("move the lifetime before this parameter")]
pub other_span: Span,
}

View file

@ -4,10 +4,9 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::codes::*;
use rustc_errors::struct_span_code_err;
use rustc_hir as hir;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::PolyTraitRef;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def_id::{CRATE_DEF_ID, DefId};
use rustc_hir::{PolyTraitRef, find_attr};
use rustc_middle::bug;
use rustc_middle::ty::{
self as ty, IsSuggestable, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
@ -603,10 +602,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
});
if let ty::AssocTag::Const = assoc_tag
&& !find_attr!(
self.tcx().get_all_attrs(assoc_item.def_id),
AttributeKind::TypeConst(_)
)
&& !self.tcx().is_type_const(assoc_item.def_id)
{
if tcx.features().min_generic_const_args() {
let mut err = self.dcx().struct_span_err(

View file

@ -3,8 +3,8 @@ use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordMap;
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, ErrorGuaranteed, MultiSpan, SuggestionStyle, listify, pluralize,
struct_span_code_err,
Applicability, Diag, ErrorGuaranteed, MultiSpan, SuggestionStyle, inline_fluent, listify,
pluralize, struct_span_code_err,
};
use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId;
@ -31,7 +31,6 @@ use crate::errors::{
self, AssocItemConstraintsNotAllowedHere, ManualImplementation, ParenthesizedFnTraitExpansion,
TraitObjectDeclaredWithNoTraits,
};
use crate::fluent_generated as fluent;
use crate::hir_ty_lowering::{AssocItemQSelf, HirTyLowerer};
impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
@ -305,7 +304,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
// was also not an exact match, so we also suggest changing it.
err.span_suggestion_verbose(
assoc_ident.span,
fluent::hir_analysis_assoc_item_not_found_similar_in_other_trait_with_bound_sugg,
inline_fluent!("...and changing the associated {$assoc_kind} name"),
suggested_name,
Applicability::MaybeIncorrect,
);

View file

@ -28,10 +28,9 @@ use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, struct_span_code_err,
};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId, find_attr};
use rustc_hir::{self as hir, AnonConst, GenericArg, GenericArgs, HirId};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::DynCompatibilityViolation;
use rustc_macros::{TypeFoldable, TypeVisitable};
@ -1423,7 +1422,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
LowerTypeRelativePathMode::Const,
)? {
TypeRelativePath::AssocItem(def_id, args) => {
if !find_attr!(self.tcx().get_all_attrs(def_id), AttributeKind::TypeConst(_)) {
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]`",
@ -1896,7 +1895,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
ty::AssocTag::Const,
) {
Ok((item_def_id, item_args)) => {
if !find_attr!(self.tcx().get_all_attrs(item_def_id), AttributeKind::TypeConst(_)) {
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]`",

View file

@ -85,12 +85,9 @@ mod variance;
pub use errors::NoVariantNamed;
use rustc_abi::{CVariadicStatus, ExternAbi};
use rustc_hir::attrs::AttributeKind;
use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::lints::DelayedLint;
use rustc_hir::{
find_attr, {self as hir},
};
use rustc_middle::mir::interpret::GlobalId;
use rustc_middle::query::Providers;
use rustc_middle::ty::{Const, Ty, TyCtxt};
@ -102,8 +99,6 @@ use rustc_trait_selection::traits;
pub use crate::collect::suggest_impl_trait;
use crate::hir_ty_lowering::HirTyLowerer;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
fn check_c_variadic_abi(tcx: TyCtxt<'_>, decl: &hir::FnDecl<'_>, abi: ExternAbi, span: Span) {
if !decl.c_variadic {
// Not even a variadic function.
@ -238,7 +233,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
}
DefKind::Const
if !tcx.generics_of(item_def_id).own_requires_monomorphization()
&& !find_attr!(tcx.get_all_attrs(item_def_id), AttributeKind::TypeConst(_)) =>
&& !tcx.is_type_const(item_def_id.into()) =>
{
// FIXME(generic_const_items): Passing empty instead of identity args is fishy but
// seems to be fine for now. Revisit this!

View file

@ -7,7 +7,6 @@ use rustc_codegen_ssa::traits::CodegenBackend;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::jobserver::{self, Proxy};
use rustc_data_structures::stable_hasher::StableHasher;
use rustc_errors::registry::Registry;
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed};
use rustc_lint::LintStore;
use rustc_middle::ty;
@ -374,9 +373,6 @@ pub struct Config {
pub make_codegen_backend:
Option<Box<dyn FnOnce(&config::Options, &Target) -> Box<dyn CodegenBackend> + Send>>,
/// Registry of diagnostics codes.
pub registry: Registry,
/// The inner atomic value is set to true when a feature marked as `internal` is
/// enabled. Makes it so that "please report a bug" is hidden, as ICEs with
/// internal features are wontfix, and they are usually the cause of the ICEs.
@ -464,7 +460,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
temps_dir,
},
bundle,
config.registry,
config.locale_resources,
config.lint_caps,
target,

View file

@ -6,8 +6,8 @@ use std::sync::atomic::AtomicBool;
use rustc_abi::Align;
use rustc_data_structures::profiling::TimePassesFormat;
use rustc_errors::ColorConfig;
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, registry};
use rustc_hir::attrs::{CollapseMacroDebuginfo, NativeLibKind};
use rustc_session::config::{
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions,
@ -72,7 +72,6 @@ where
sessopts,
io,
None,
registry::Registry::new(&[]),
vec![],
Default::default(),
target,

View file

@ -1,125 +0,0 @@
use std::str::Chars;
pub enum FrontmatterAllowed {
Yes,
No,
}
/// Peekable iterator over a char sequence.
///
/// Next characters can be peeked via `first` method,
/// and position can be shifted forward via `bump` method.
pub struct Cursor<'a> {
len_remaining: usize,
/// Iterator over chars. Slightly faster than a &str.
chars: Chars<'a>,
pub(crate) frontmatter_allowed: FrontmatterAllowed,
#[cfg(debug_assertions)]
prev: char,
}
pub(crate) const EOF_CHAR: char = '\0';
impl<'a> Cursor<'a> {
pub fn new(input: &'a str, frontmatter_allowed: FrontmatterAllowed) -> Cursor<'a> {
Cursor {
len_remaining: input.len(),
chars: input.chars(),
frontmatter_allowed,
#[cfg(debug_assertions)]
prev: EOF_CHAR,
}
}
pub fn as_str(&self) -> &'a str {
self.chars.as_str()
}
/// Returns the last eaten symbol (or `'\0'` in release builds).
/// (For debug assertions only.)
pub(crate) fn prev(&self) -> char {
#[cfg(debug_assertions)]
{
self.prev
}
#[cfg(not(debug_assertions))]
{
EOF_CHAR
}
}
/// Peeks the next symbol from the input stream without consuming it.
/// If requested position doesn't exist, `EOF_CHAR` is returned.
/// However, getting `EOF_CHAR` doesn't always mean actual end of file,
/// it should be checked with `is_eof` method.
pub fn first(&self) -> char {
// `.next()` optimizes better than `.nth(0)`
self.chars.clone().next().unwrap_or(EOF_CHAR)
}
/// Peeks the second symbol from the input stream without consuming it.
pub(crate) fn second(&self) -> char {
// `.next()` optimizes better than `.nth(1)`
let mut iter = self.chars.clone();
iter.next();
iter.next().unwrap_or(EOF_CHAR)
}
/// Peeks the third symbol from the input stream without consuming it.
pub fn third(&self) -> char {
// `.next()` optimizes better than `.nth(2)`
let mut iter = self.chars.clone();
iter.next();
iter.next();
iter.next().unwrap_or(EOF_CHAR)
}
/// Checks if there is nothing more to consume.
pub(crate) fn is_eof(&self) -> bool {
self.chars.as_str().is_empty()
}
/// Returns amount of already consumed symbols.
pub(crate) fn pos_within_token(&self) -> u32 {
(self.len_remaining - self.chars.as_str().len()) as u32
}
/// Resets the number of bytes consumed to 0.
pub(crate) fn reset_pos_within_token(&mut self) {
self.len_remaining = self.chars.as_str().len();
}
/// Moves to the next character.
pub(crate) fn bump(&mut self) -> Option<char> {
let c = self.chars.next()?;
#[cfg(debug_assertions)]
{
self.prev = c;
}
Some(c)
}
/// Moves to a substring by a number of bytes.
pub(crate) fn bump_bytes(&mut self, n: usize) {
self.chars = self.as_str()[n..].chars();
}
/// Eats symbols while predicate returns true or until the end of file is reached.
pub(crate) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
// It was tried making optimized version of this for eg. line comments, but
// LLVM can inline all of this and compile it down to fast iteration over bytes.
while predicate(self.first()) && !self.is_eof() {
self.bump();
}
}
pub(crate) fn eat_until(&mut self, byte: u8) {
self.chars = match memchr::memchr(byte, self.as_str().as_bytes()) {
Some(index) => self.as_str()[index..].chars(),
None => "".chars(),
}
}
}

View file

@ -25,15 +25,13 @@
#![deny(unstable_features)]
// tidy-alphabetical-end
mod cursor;
#[cfg(test)]
mod tests;
use std::str::Chars;
use LiteralKind::*;
use TokenKind::*;
use cursor::EOF_CHAR;
pub use cursor::{Cursor, FrontmatterAllowed};
pub use unicode_ident::UNICODE_VERSION;
use unicode_properties::UnicodeEmoji;
@ -407,7 +405,129 @@ pub fn is_ident(string: &str) -> bool {
}
}
impl Cursor<'_> {
pub enum FrontmatterAllowed {
Yes,
No,
}
/// Peekable iterator over a char sequence.
///
/// Next characters can be peeked via `first` method,
/// and position can be shifted forward via `bump` method.
pub struct Cursor<'a> {
len_remaining: usize,
/// Iterator over chars. Slightly faster than a &str.
chars: Chars<'a>,
pub(crate) frontmatter_allowed: FrontmatterAllowed,
#[cfg(debug_assertions)]
prev: char,
}
const EOF_CHAR: char = '\0';
impl<'a> Cursor<'a> {
pub fn new(input: &'a str, frontmatter_allowed: FrontmatterAllowed) -> Cursor<'a> {
Cursor {
len_remaining: input.len(),
chars: input.chars(),
frontmatter_allowed,
#[cfg(debug_assertions)]
prev: EOF_CHAR,
}
}
pub fn as_str(&self) -> &'a str {
self.chars.as_str()
}
/// Returns the last eaten symbol (or `'\0'` in release builds).
/// (For debug assertions only.)
pub(crate) fn prev(&self) -> char {
#[cfg(debug_assertions)]
{
self.prev
}
#[cfg(not(debug_assertions))]
{
EOF_CHAR
}
}
/// Peeks the next symbol from the input stream without consuming it.
/// If requested position doesn't exist, `EOF_CHAR` is returned.
/// However, getting `EOF_CHAR` doesn't always mean actual end of file,
/// it should be checked with `is_eof` method.
pub fn first(&self) -> char {
// `.next()` optimizes better than `.nth(0)`
self.chars.clone().next().unwrap_or(EOF_CHAR)
}
/// Peeks the second symbol from the input stream without consuming it.
pub(crate) fn second(&self) -> char {
// `.next()` optimizes better than `.nth(1)`
let mut iter = self.chars.clone();
iter.next();
iter.next().unwrap_or(EOF_CHAR)
}
/// Peeks the third symbol from the input stream without consuming it.
pub fn third(&self) -> char {
// `.next()` optimizes better than `.nth(2)`
let mut iter = self.chars.clone();
iter.next();
iter.next();
iter.next().unwrap_or(EOF_CHAR)
}
/// Checks if there is nothing more to consume.
pub(crate) fn is_eof(&self) -> bool {
self.chars.as_str().is_empty()
}
/// Returns amount of already consumed symbols.
pub(crate) fn pos_within_token(&self) -> u32 {
(self.len_remaining - self.chars.as_str().len()) as u32
}
/// Resets the number of bytes consumed to 0.
pub(crate) fn reset_pos_within_token(&mut self) {
self.len_remaining = self.chars.as_str().len();
}
/// Moves to the next character.
pub(crate) fn bump(&mut self) -> Option<char> {
let c = self.chars.next()?;
#[cfg(debug_assertions)]
{
self.prev = c;
}
Some(c)
}
/// Moves to a substring by a number of bytes.
pub(crate) fn bump_bytes(&mut self, n: usize) {
self.chars = self.as_str()[n..].chars();
}
/// Eats symbols while predicate returns true or until the end of file is reached.
pub(crate) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
// It was tried making optimized version of this for eg. line comments, but
// LLVM can inline all of this and compile it down to fast iteration over bytes.
while predicate(self.first()) && !self.is_eof() {
self.bump();
}
}
pub(crate) fn eat_until(&mut self, byte: u8) {
self.chars = match memchr::memchr(byte, self.as_str().as_bytes()) {
Some(index) => self.as_str()[index..].chars(),
None => "".chars(),
}
}
/// Parses a token from the input string.
pub fn advance_token(&mut self) -> Token {
let Some(first_char) = self.bump() else {

View file

@ -1886,10 +1886,15 @@ impl<'tcx> TyCtxt<'tcx> {
self.is_lang_item(self.parent(def_id), LangItem::AsyncDropInPlace)
}
pub fn type_const_span(self, def_id: DefId) -> Option<Span> {
matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst)
.then(|| find_attr!(self.get_all_attrs(def_id), AttributeKind::TypeConst(sp) => *sp))
.flatten()
}
/// Check if the given `def_id` is a const with the `#[type_const]` attribute.
pub fn is_type_const(self, def_id: DefId) -> bool {
matches!(self.def_kind(def_id), DefKind::Const | DefKind::AssocConst)
&& find_attr!(self.get_all_attrs(def_id), AttributeKind::TypeConst(_))
self.type_const_span(def_id).is_some()
}
/// Returns the movability of the coroutine of `def_id`, or panics

View file

@ -3,7 +3,7 @@
use std::borrow::Cow;
use std::path::PathBuf;
use rustc_ast::token::Token;
use rustc_ast::token::{self, InvisibleOrigin, MetaVarKind, Token};
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{Path, Visibility};
use rustc_errors::codes::*;
@ -17,7 +17,6 @@ use rustc_span::edition::{Edition, LATEST_STABLE_EDITION};
use rustc_span::{Ident, Span, Symbol};
use crate::fluent_generated as fluent;
use crate::parser::{ForbiddenLetReason, TokenDescription};
#[derive(Diagnostic)]
#[diag(parse_maybe_report_ambiguous_plus)]
@ -3710,3 +3709,64 @@ pub(crate) struct StructLiteralWithoutPathLate {
#[suggestion(applicability = "has-placeholders", code = "/* Type */ ", style = "verbose")]
pub suggestion_span: Span,
}
/// Used to forbid `let` expressions in certain syntactic locations.
#[derive(Clone, Copy, Subdiagnostic)]
pub(crate) enum ForbiddenLetReason {
/// `let` is not valid and the source environment is not important
OtherForbidden,
/// A let chain with the `||` operator
#[note(parse_not_supported_or)]
NotSupportedOr(#[primary_span] Span),
/// A let chain with invalid parentheses
///
/// For example, `let 1 = 1 && (expr && expr)` is allowed
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
#[note(parse_not_supported_parentheses)]
NotSupportedParentheses(#[primary_span] Span),
}
#[derive(Debug, rustc_macros::Subdiagnostic)]
#[suggestion(
parse_misspelled_kw,
applicability = "machine-applicable",
code = "{similar_kw}",
style = "verbose"
)]
pub(crate) struct MisspelledKw {
// We use a String here because `Symbol::into_diag_arg` calls `Symbol::to_ident_string`, which
// prefix the keyword with a `r#` because it aims to print the symbol as an identifier.
pub similar_kw: String,
#[primary_span]
pub span: Span,
pub is_incorrect_case: bool,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(super) enum TokenDescription {
ReservedIdentifier,
Keyword,
ReservedKeyword,
DocComment,
// Expanded metavariables are wrapped in invisible delimiters which aren't
// pretty-printed. In error messages we must handle these specially
// otherwise we get confusing things in messages like "expected `(`, found
// ``". It's better to say e.g. "expected `(`, found type metavariable".
MetaVar(MetaVarKind),
}
impl TokenDescription {
pub(super) fn from_token(token: &Token) -> Option<Self> {
match token.kind {
_ if token.is_special_ident() => Some(TokenDescription::ReservedIdentifier),
_ if token.is_used_keyword() => Some(TokenDescription::Keyword),
_ if token.is_unused_keyword() => Some(TokenDescription::ReservedKeyword),
token::DocComment(..) => Some(TokenDescription::DocComment),
token::OpenInvisible(InvisibleOrigin::MetaVar(kind)) => {
Some(TokenDescription::MetaVar(kind))
}
_ => None,
}
}
}

View file

@ -35,10 +35,10 @@ use crate::errors::{
ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg, GenericParamsWithoutAngleBrackets,
GenericParamsWithoutAngleBracketsSugg, HelpIdentifierStartsWithNumber, HelpUseLatestEdition,
InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, IncorrectUseOfUse,
PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, SuggAddMissingLetStmt,
SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator, TernaryOperatorSuggestion,
UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
MisspelledKw, PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg,
SelfParamNotFirst, StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg,
SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma, TernaryOperator,
TernaryOperatorSuggestion, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
};
use crate::parser::FnContext;
@ -212,22 +212,6 @@ impl std::fmt::Display for UnaryFixity {
}
}
#[derive(Debug, rustc_macros::Subdiagnostic)]
#[suggestion(
parse_misspelled_kw,
applicability = "machine-applicable",
code = "{similar_kw}",
style = "verbose"
)]
struct MisspelledKw {
// We use a String here because `Symbol::into_diag_arg` calls `Symbol::to_ident_string`, which
// prefix the keyword with a `r#` because it aims to print the symbol as an identifier.
similar_kw: String,
#[primary_span]
span: Span,
is_incorrect_case: bool,
}
/// Checks if the given `lookup` identifier is similar to any keyword symbol in `candidates`.
///
/// This is a specialized version of [`Symbol::find_similar`] that constructs an error when a

View file

@ -21,7 +21,6 @@ use rustc_ast::{
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{Applicability, Diag, PResult, StashKey, Subdiagnostic};
use rustc_literal_escaper::unescape_char;
use rustc_macros::Subdiagnostic;
use rustc_session::errors::{ExprParenthesesNeeded, report_lit_error};
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
@ -2774,7 +2773,7 @@ impl<'a> Parser<'a> {
let recovered = if !restrictions.contains(Restrictions::ALLOW_LET) {
let err = errors::ExpectedExpressionFoundLet {
span: self.token.span,
reason: ForbiddenLetReason::OtherForbidden,
reason: errors::ForbiddenLetReason::OtherForbidden,
missing_let: None,
comparison: None,
};
@ -4189,22 +4188,6 @@ pub(crate) fn could_be_unclosed_char_literal(ident: Ident) -> bool {
&& unescape_char(ident.without_first_quote().name.as_str()).is_ok()
}
/// Used to forbid `let` expressions in certain syntactic locations.
#[derive(Clone, Copy, Subdiagnostic)]
pub(crate) enum ForbiddenLetReason {
/// `let` is not valid and the source environment is not important
OtherForbidden,
/// A let chain with the `||` operator
#[note(parse_not_supported_or)]
NotSupportedOr(#[primary_span] Span),
/// A let chain with invalid parentheses
///
/// For example, `let 1 = 1 && (expr && expr)` is allowed
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
#[note(parse_not_supported_parentheses)]
NotSupportedParentheses(#[primary_span] Span),
}
/// Whether let chains are allowed on all editions, or it's edition dependent (allowed only on
/// 2024 and later). In case of edition dependence, specify the currently present edition.
pub enum LetChainsPolicy {
@ -4225,7 +4208,7 @@ struct CondChecker<'a> {
parser: &'a Parser<'a>,
let_chains_policy: LetChainsPolicy,
depth: u32,
forbid_let_reason: Option<ForbiddenLetReason>,
forbid_let_reason: Option<errors::ForbiddenLetReason>,
missing_let: Option<errors::MaybeMissingLet>,
comparison: Option<errors::MaybeComparison>,
found_incorrect_let_chain: Option<ErrorGuaranteed>,
@ -4248,14 +4231,13 @@ impl<'a> CondChecker<'a> {
impl MutVisitor for CondChecker<'_> {
fn visit_expr(&mut self, e: &mut Expr) {
self.depth += 1;
use ForbiddenLetReason::*;
let span = e.span;
match e.kind {
ExprKind::Let(_, _, _, ref mut recovered @ Recovered::No) => {
if let Some(reason) = self.forbid_let_reason {
let error = match reason {
NotSupportedOr(or_span) => {
errors::ForbiddenLetReason::NotSupportedOr(or_span) => {
self.parser.dcx().emit_err(errors::OrInLetChain { span: or_span })
}
_ => {
@ -4289,24 +4271,27 @@ impl MutVisitor for CondChecker<'_> {
mut_visit::walk_expr(self, e);
}
ExprKind::Binary(Spanned { node: BinOpKind::Or, span: or_span }, _, _)
if let None | Some(NotSupportedOr(_)) = self.forbid_let_reason =>
if let None | Some(errors::ForbiddenLetReason::NotSupportedOr(_)) =
self.forbid_let_reason =>
{
let forbid_let_reason = self.forbid_let_reason;
self.forbid_let_reason = Some(NotSupportedOr(or_span));
self.forbid_let_reason = Some(errors::ForbiddenLetReason::NotSupportedOr(or_span));
mut_visit::walk_expr(self, e);
self.forbid_let_reason = forbid_let_reason;
}
ExprKind::Paren(ref inner)
if let None | Some(NotSupportedParentheses(_)) = self.forbid_let_reason =>
if let None | Some(errors::ForbiddenLetReason::NotSupportedParentheses(_)) =
self.forbid_let_reason =>
{
let forbid_let_reason = self.forbid_let_reason;
self.forbid_let_reason = Some(NotSupportedParentheses(inner.span));
self.forbid_let_reason =
Some(errors::ForbiddenLetReason::NotSupportedParentheses(inner.span));
mut_visit::walk_expr(self, e);
self.forbid_let_reason = forbid_let_reason;
}
ExprKind::Assign(ref lhs, _, span) => {
let forbid_let_reason = self.forbid_let_reason;
self.forbid_let_reason = Some(OtherForbidden);
self.forbid_let_reason = Some(errors::ForbiddenLetReason::OtherForbidden);
let missing_let = self.missing_let;
if let ExprKind::Binary(_, _, rhs) = &lhs.kind
&& let ExprKind::Path(_, _)
@ -4339,7 +4324,7 @@ impl MutVisitor for CondChecker<'_> {
| ExprKind::Tup(_)
| ExprKind::Paren(_) => {
let forbid_let_reason = self.forbid_let_reason;
self.forbid_let_reason = Some(OtherForbidden);
self.forbid_let_reason = Some(errors::ForbiddenLetReason::OtherForbidden);
mut_visit::walk_expr(self, e);
self.forbid_let_reason = forbid_let_reason;
}
@ -4347,7 +4332,7 @@ impl MutVisitor for CondChecker<'_> {
| ExprKind::Type(ref mut op, _)
| ExprKind::UnsafeBinderCast(_, ref mut op, _) => {
let forbid_let_reason = self.forbid_let_reason;
self.forbid_let_reason = Some(OtherForbidden);
self.forbid_let_reason = Some(errors::ForbiddenLetReason::OtherForbidden);
self.visit_expr(op);
self.forbid_let_reason = forbid_let_reason;
}

View file

@ -20,7 +20,6 @@ use std::{fmt, mem, slice};
use attr_wrapper::{AttrWrapper, UsePreAttrPos};
pub use diagnostics::AttemptLocalParseRecovery;
pub(crate) use expr::ForbiddenLetReason;
// Public to use it for custom `if` expressions in rustfmt forks like https://github.com/tucant/rustfmt
pub use expr::LetChainsPolicy;
pub(crate) use item::{FnContext, FnParseMode};
@ -50,7 +49,7 @@ use token_type::TokenTypeSet;
pub use token_type::{ExpKeywordPair, ExpTokenPair, TokenType};
use tracing::debug;
use crate::errors::{self, IncorrectVisibilityRestriction, NonStringAbiLiteral};
use crate::errors::{self, IncorrectVisibilityRestriction, NonStringAbiLiteral, TokenDescription};
use crate::exp;
#[cfg(test)]
@ -308,35 +307,6 @@ impl From<bool> for Trailing {
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(super) enum TokenDescription {
ReservedIdentifier,
Keyword,
ReservedKeyword,
DocComment,
// Expanded metavariables are wrapped in invisible delimiters which aren't
// pretty-printed. In error messages we must handle these specially
// otherwise we get confusing things in messages like "expected `(`, found
// ``". It's better to say e.g. "expected `(`, found type metavariable".
MetaVar(MetaVarKind),
}
impl TokenDescription {
pub(super) fn from_token(token: &Token) -> Option<Self> {
match token.kind {
_ if token.is_special_ident() => Some(TokenDescription::ReservedIdentifier),
_ if token.is_used_keyword() => Some(TokenDescription::Keyword),
_ if token.is_unused_keyword() => Some(TokenDescription::ReservedKeyword),
token::DocComment(..) => Some(TokenDescription::DocComment),
token::OpenInvisible(InvisibleOrigin::MetaVar(kind)) => {
Some(TokenDescription::MetaVar(kind))
}
_ => None,
}
}
}
pub fn token_descr(token: &Token) -> String {
let s = pprust::token_to_string(token).to_string();

View file

@ -1,11 +1,12 @@
use rustc_hir::Attribute;
use rustc_hir::attrs::{AttributeKind, RustcAbiAttrKind};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::find_attr;
use rustc_middle::span_bug;
use rustc_middle::ty::layout::{FnAbiError, LayoutError};
use rustc_middle::ty::{self, GenericArgs, Instance, Ty, TyCtxt};
use rustc_span::Span;
use rustc_span::source_map::Spanned;
use rustc_span::sym;
use rustc_target::callconv::FnAbi;
use super::layout_test::ensure_wf;
@ -17,17 +18,19 @@ pub fn test_abi(tcx: TyCtxt<'_>) {
return;
}
for id in tcx.hir_crate_items(()).definitions() {
for attr in tcx.get_attrs(id, sym::rustc_abi) {
match tcx.def_kind(id) {
DefKind::Fn | DefKind::AssocFn => {
dump_abi_of_fn_item(tcx, id, attr);
}
DefKind::TyAlias => {
dump_abi_of_fn_type(tcx, id, attr);
}
_ => {
tcx.dcx().emit_err(AbiInvalidAttribute { span: tcx.def_span(id) });
}
let Some((attr_span, attr_kind)) = find_attr!(tcx.get_all_attrs(id), AttributeKind::RustcAbi{ attr_span, kind } => (*attr_span, *kind))
else {
continue;
};
match tcx.def_kind(id) {
DefKind::Fn | DefKind::AssocFn => {
dump_abi_of_fn_item(tcx, id, attr_span, attr_kind);
}
DefKind::TyAlias => {
dump_abi_of_fn_type(tcx, id, attr_span, attr_kind);
}
_ => {
tcx.dcx().emit_err(AbiInvalidAttribute { span: tcx.def_span(id) });
}
}
}
@ -49,7 +52,12 @@ fn unwrap_fn_abi<'tcx>(
}
}
fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
fn dump_abi_of_fn_item(
tcx: TyCtxt<'_>,
item_def_id: LocalDefId,
attr_span: Span,
attr_kind: RustcAbiAttrKind,
) {
let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id);
let args = GenericArgs::identity_for_item(tcx, item_def_id);
let instance = match Instance::try_resolve(tcx, typing_env, item_def_id.into(), args) {
@ -75,22 +83,18 @@ fn dump_abi_of_fn_item(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
// Check out the `#[rustc_abi(..)]` attribute to tell what to dump.
// The `..` are the names of fields to dump.
let meta_items = attr.meta_item_list().unwrap_or_default();
for meta_item in meta_items {
match meta_item.name() {
Some(sym::debug) => {
let fn_name = tcx.item_name(item_def_id);
tcx.dcx().emit_err(AbiOf {
span: tcx.def_span(item_def_id),
fn_name,
// FIXME: using the `Debug` impl here isn't ideal.
fn_abi: format!("{:#?}", abi),
});
}
_ => {
tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
}
match attr_kind {
RustcAbiAttrKind::Debug => {
let fn_name = tcx.item_name(item_def_id);
tcx.dcx().emit_err(AbiOf {
span: tcx.def_span(item_def_id),
fn_name,
// FIXME: using the `Debug` impl here isn't ideal.
fn_abi: format!("{:#?}", abi),
});
}
_ => {
tcx.dcx().emit_err(UnrecognizedArgument { span: attr_span });
}
}
}
@ -109,24 +113,29 @@ fn test_abi_eq<'tcx>(abi1: &'tcx FnAbi<'tcx, Ty<'tcx>>, abi2: &'tcx FnAbi<'tcx,
&& abi1.args.iter().zip(abi2.args.iter()).all(|(arg1, arg2)| arg1.eq_abi(arg2))
}
fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribute) {
fn dump_abi_of_fn_type(
tcx: TyCtxt<'_>,
item_def_id: LocalDefId,
attr_span: Span,
attr_kind: RustcAbiAttrKind,
) {
let typing_env = ty::TypingEnv::post_analysis(tcx, item_def_id);
let ty = tcx.type_of(item_def_id).instantiate_identity();
let span = tcx.def_span(item_def_id);
if !ensure_wf(tcx, typing_env, ty, item_def_id, span) {
return;
}
let meta_items = attr.meta_item_list().unwrap_or_default();
for meta_item in meta_items {
match meta_item.name() {
Some(sym::debug) => {
let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
span_bug!(
meta_item.span(),
"`#[rustc_abi(debug)]` on a type alias requires function pointer type"
);
};
let abi = unwrap_fn_abi(
match attr_kind {
RustcAbiAttrKind::Debug => {
let ty::FnPtr(sig_tys, hdr) = ty.kind() else {
span_bug!(
attr_span,
"`#[rustc_abi(debug)]` on a type alias requires function pointer type"
);
};
let abi =
unwrap_fn_abi(
tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((
sig_tys.with(*hdr),
/* extra_args */ ty::List::empty(),
@ -135,61 +144,57 @@ fn dump_abi_of_fn_type(tcx: TyCtxt<'_>, item_def_id: LocalDefId, attr: &Attribut
item_def_id,
);
let fn_name = tcx.item_name(item_def_id);
tcx.dcx().emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) });
}
Some(sym::assert_eq) => {
let ty::Tuple(fields) = ty.kind() else {
span_bug!(
meta_item.span(),
"`#[rustc_abi(assert_eq)]` on a type alias requires pair type"
);
};
let [field1, field2] = ***fields else {
span_bug!(
meta_item.span(),
"`#[rustc_abi(assert_eq)]` on a type alias requires pair type"
);
};
let ty::FnPtr(sig_tys1, hdr1) = field1.kind() else {
span_bug!(
meta_item.span(),
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
);
};
let abi1 = unwrap_fn_abi(
tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((
sig_tys1.with(*hdr1),
/* extra_args */ ty::List::empty(),
))),
tcx,
item_def_id,
let fn_name = tcx.item_name(item_def_id);
tcx.dcx().emit_err(AbiOf { span, fn_name, fn_abi: format!("{:#?}", abi) });
}
RustcAbiAttrKind::AssertEq => {
let ty::Tuple(fields) = ty.kind() else {
span_bug!(
attr_span,
"`#[rustc_abi(assert_eq)]` on a type alias requires pair type"
);
let ty::FnPtr(sig_tys2, hdr2) = field2.kind() else {
span_bug!(
meta_item.span(),
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
);
};
let abi2 = unwrap_fn_abi(
tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((
sig_tys2.with(*hdr2),
/* extra_args */ ty::List::empty(),
))),
tcx,
item_def_id,
};
let [field1, field2] = ***fields else {
span_bug!(
attr_span,
"`#[rustc_abi(assert_eq)]` on a type alias requires pair type"
);
};
let ty::FnPtr(sig_tys1, hdr1) = field1.kind() else {
span_bug!(
attr_span,
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
);
};
let abi1 = unwrap_fn_abi(
tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((
sig_tys1.with(*hdr1),
/* extra_args */ ty::List::empty(),
))),
tcx,
item_def_id,
);
let ty::FnPtr(sig_tys2, hdr2) = field2.kind() else {
span_bug!(
attr_span,
"`#[rustc_abi(assert_eq)]` on a type alias requires pair of function pointer types"
);
};
let abi2 = unwrap_fn_abi(
tcx.fn_abi_of_fn_ptr(typing_env.as_query_input((
sig_tys2.with(*hdr2),
/* extra_args */ ty::List::empty(),
))),
tcx,
item_def_id,
);
if !test_abi_eq(abi1, abi2) {
tcx.dcx().emit_err(AbiNe {
span,
left: format!("{:#?}", abi1),
right: format!("{:#?}", abi2),
});
}
}
_ => {
tcx.dcx().emit_err(UnrecognizedArgument { span: meta_item.span() });
if !test_abi_eq(abi1, abi2) {
tcx.dcx().emit_err(AbiNe {
span,
left: format!("{:#?}", abi1),
right: format!("{:#?}", abi2),
});
}
}
}

View file

@ -287,6 +287,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::ReexportTestHarnessMain(..)
// handled below this loop and elsewhere
| AttributeKind::Repr { .. }
| AttributeKind::RustcAbi { .. }
| AttributeKind::RustcAllocator
| AttributeKind::RustcAllocatorZeroed
| AttributeKind::RustcAllocatorZeroedVariant { .. }
@ -307,6 +308,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcDumpUserArgs
| AttributeKind::RustcDumpVtable(..)
| AttributeKind::RustcDynIncompatibleTrait(..)
| AttributeKind::RustcEffectiveVisibility
| AttributeKind::RustcHasIncoherentInherentImpls
| AttributeKind::RustcHiddenTypeOfOpaques
| AttributeKind::RustcIfThisChanged(..)
@ -392,7 +394,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::rustc_conversion_suggestion
| sym::rustc_deprecated_safe_2024
| sym::rustc_test_marker
| sym::rustc_abi
| sym::rustc_layout
| sym::rustc_proc_macro_decls
| sym::rustc_never_type_options
@ -401,7 +402,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::rustc_regions
| sym::rustc_strict_coherence
| sym::rustc_mir
| sym::rustc_effective_visibility
| sym::rustc_outlives
| sym::rustc_symbol_name
| sym::rustc_evaluate_where_clauses

View file

@ -876,7 +876,7 @@ pub struct TestReachabilityVisitor<'a, 'tcx> {
impl<'a, 'tcx> TestReachabilityVisitor<'a, 'tcx> {
fn effective_visibility_diagnostic(&self, def_id: LocalDefId) {
if self.tcx.has_attr(def_id, sym::rustc_effective_visibility) {
if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::RustcEffectiveVisibility) {
let mut error_msg = String::new();
let span = self.tcx.def_span(def_id.to_def_id());
if let Some(effective_vis) = self.effective_visibilities.effective_vis(def_id) {

View file

@ -967,7 +967,6 @@ pub fn build_session(
sopts: config::Options,
io: CompilerIO,
fluent_bundle: Option<Arc<rustc_errors::FluentBundle>>,
registry: rustc_errors::registry::Registry,
fluent_resources: Vec<&'static str>,
driver_lint_caps: FxHashMap<lint::LintId, lint::Level>,
target: Target,
@ -996,9 +995,8 @@ pub fn build_session(
let source_map = rustc_span::source_map::get_source_map().unwrap();
let emitter = default_emitter(&sopts, Arc::clone(&source_map), translator);
let mut dcx = DiagCtxt::new(emitter)
.with_flags(sopts.unstable_opts.dcx_flags(can_emit_warnings))
.with_registry(registry);
let mut dcx =
DiagCtxt::new(emitter).with_flags(sopts.unstable_opts.dcx_flags(can_emit_warnings));
if let Some(ice_file) = ice_file {
dcx = dcx.with_ice_file(ice_file);
}

View file

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

View file

@ -1,470 +0,0 @@
trait_selection_actual_impl_expl_but_actually_implemented_for_ty = ...but `{$trait_path}` is actually implemented for the type `{$ty}`{$has_lifetime ->
[true] , for some specific lifetime `'{$lifetime}`
*[false] {""}
}
trait_selection_actual_impl_expl_but_actually_implements_trait = ...but it actually implements `{$trait_path}`{$has_lifetime ->
[true] , for some specific lifetime `'{$lifetime}`
*[false] {""}
}
trait_selection_actual_impl_expl_but_actually_ty_implements = ...but `{$ty}` actually implements `{$trait_path}`{$has_lifetime ->
[true] , for some specific lifetime `'{$lifetime}`
*[false] {""}
}
trait_selection_actual_impl_expl_expected_other_any = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...
trait_selection_actual_impl_expl_expected_other_nothing = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$ty_or_sig}` must implement `{$trait_path}`
trait_selection_actual_impl_expl_expected_other_some = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...
trait_selection_actual_impl_expl_expected_other_two = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
trait_selection_actual_impl_expl_expected_passive_any = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any lifetime `'{$lifetime_1}`...
trait_selection_actual_impl_expl_expected_passive_nothing = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`
trait_selection_actual_impl_expl_expected_passive_some = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for some specific lifetime `'{$lifetime_1}`...
trait_selection_actual_impl_expl_expected_passive_two = {$leading_ellipsis ->
[true] ...
*[false] {""}
}`{$trait_path}` would have to be implemented for the type `{$ty_or_sig}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
trait_selection_actual_impl_expl_expected_signature_any = {$leading_ellipsis ->
[true] ...
*[false] {""}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any lifetime `'{$lifetime_1}`...
trait_selection_actual_impl_expl_expected_signature_nothing = {$leading_ellipsis ->
[true] ...
*[false] {""}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`
trait_selection_actual_impl_expl_expected_signature_some = {$leading_ellipsis ->
[true] ...
*[false] {""}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for some specific lifetime `'{$lifetime_1}`...
trait_selection_actual_impl_expl_expected_signature_two = {$leading_ellipsis ->
[true] ...
*[false] {""}
}closure with signature `{$ty_or_sig}` must implement `{$trait_path}`, for any two lifetimes `'{$lifetime_1}` and `'{$lifetime_2}`...
trait_selection_adjust_signature_borrow = consider adjusting the signature so it borrows its {$len ->
[one] argument
*[other] arguments
}
trait_selection_adjust_signature_remove_borrow = consider adjusting the signature so it does not borrow its {$len ->
[one] argument
*[other] arguments
}
trait_selection_ascribe_user_type_prove_predicate = ...so that the where clause holds
trait_selection_await_both_futures = consider `await`ing on both `Future`s
trait_selection_await_future = consider `await`ing on the `Future`
trait_selection_await_note = calling an async function returns a future
trait_selection_but_calling_introduces = {$has_param_name ->
[true] `{$param_name}`
*[false] `fn` parameter
} has {$lifetime_kind ->
[true] lifetime `{$lifetime}`
*[false] an anonymous lifetime `'_`
} but calling `{$assoc_item}` introduces an implicit `'static` lifetime requirement
.label1 = {$has_lifetime ->
[true] lifetime `{$lifetime}`
*[false] an anonymous lifetime `'_`
}
.label2 = ...is used and required to live as long as `'static` here because of an implicit lifetime bound on the {$has_impl_path ->
[true] `impl` of `{$impl_path}`
*[false] inherent `impl`
}
trait_selection_but_needs_to_satisfy = {$has_param_name ->
[true] `{$param_name}`
*[false] `fn` parameter
} has {$has_lifetime ->
[true] lifetime `{$lifetime}`
*[false] an anonymous lifetime `'_`
} but it needs to satisfy a `'static` lifetime requirement
.influencer = this data with {$has_lifetime ->
[true] lifetime `{$lifetime}`
*[false] an anonymous lifetime `'_`
}...
.require = {$spans_empty ->
*[true] ...is used and required to live as long as `'static` here
[false] ...and is required to live as long as `'static` here
}
.used_here = ...is used here...
.introduced_by_bound = `'static` lifetime requirement introduced by this bound
trait_selection_closure_fn_mut_label = closure is `{$trait_prefix}FnMut` because it mutates the variable `{$place}` here
trait_selection_closure_fn_once_label = closure is `{$trait_prefix}FnOnce` because it moves the variable `{$place}` out of its environment
trait_selection_closure_kind_mismatch = expected a closure that implements the `{$trait_prefix}{$expected}` trait, but this closure only implements `{$trait_prefix}{$found}`
.label = this closure implements `{$trait_prefix}{$found}`, not `{$trait_prefix}{$expected}`
trait_selection_closure_kind_requirement = the requirement to implement `{$trait_prefix}{$expected}` derives from here
trait_selection_compare_impl_item_obligation = ...so that the definition in impl matches the definition from the trait
trait_selection_consider_specifying_length = consider specifying the actual array length
trait_selection_coro_closure_not_fn = {$coro_kind}closure does not implement `{$kind}` because it captures state from its environment
trait_selection_data_flows = ...but data{$label_var1_exists ->
[true] {" "}from `{$label_var1}`
*[false] {""}
} flows{$label_var2_exists ->
[true] {" "}into `{$label_var2}`
*[false] {""}
} here
trait_selection_data_lifetime_flow = ...but data with one lifetime flows into the other here
trait_selection_data_returned = ...but data{$label_var1_exists ->
[true] {" "}from `{$label_var1}`
*[false] {""}
} is returned here
trait_selection_declared_different = this parameter and the return type are declared with different lifetimes...
trait_selection_declared_multiple = this type is declared with multiple lifetimes...
trait_selection_disallowed_positional_argument = positional format arguments are not allowed here
.help = only named format arguments with the name of one of the generic types are allowed in this context
trait_selection_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
trait_selection_dtcs_has_lifetime_req_label = this has an implicit `'static` lifetime requirement
trait_selection_dtcs_has_req_note = the used `impl` has a `'static` requirement
trait_selection_dtcs_introduces_requirement = calling this method introduces the `impl`'s `'static` requirement
trait_selection_dtcs_suggestion = consider relaxing the implicit `'static` requirement
trait_selection_explicit_lifetime_required_sugg_with_ident = add explicit lifetime `{$named}` to the type of `{$simple_ident}`
trait_selection_explicit_lifetime_required_sugg_with_param_type = add explicit lifetime `{$named}` to type
trait_selection_explicit_lifetime_required_with_ident = explicit lifetime required in the type of `{$simple_ident}`
.label = lifetime `{$named}` required
trait_selection_explicit_lifetime_required_with_param_type = explicit lifetime required in parameter type
.label = lifetime `{$named}` required
trait_selection_fn_consider_casting = consider casting the fn item to a fn pointer: `{$casting}`
trait_selection_fn_consider_casting_both = consider casting both fn items to fn pointers using `as {$sig}`
trait_selection_fn_uniq_types = different fn items have unique types, even if their signatures are the same
trait_selection_fps_cast = consider casting to a fn pointer
trait_selection_fps_cast_both = consider casting both fn items to fn pointers using `as {$expected_sig}`
trait_selection_fps_items_are_distinct = fn items are distinct from fn pointers
trait_selection_fps_remove_ref = consider removing the reference
trait_selection_fps_use_ref = consider using a reference
trait_selection_fulfill_req_lifetime = the type `{$ty}` does not fulfill the required lifetime
trait_selection_ignored_diagnostic_option = `{$option_name}` is ignored due to previous definition of `{$option_name}`
.other_label = `{$option_name}` is first declared here
.label = `{$option_name}` is already declared here
trait_selection_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
trait_selection_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
trait_selection_inherent_projection_normalization_overflow = overflow evaluating associated type `{$ty}`
trait_selection_invalid_format_specifier = invalid format specifier
.help = no format specifier are supported in this position
trait_selection_label_bad = {$bad_kind ->
*[other] cannot infer type
[more_info] cannot infer {$prefix_kind ->
*[type] type for {$prefix}
[const_with_param] the value of const parameter
[const] the value of the constant
} `{$name}`{$has_parent ->
[true] {" "}declared on the {$parent_prefix} `{$parent_name}`
*[false] {""}
}
}
trait_selection_lf_bound_not_satisfied = lifetime bound not satisfied
trait_selection_lifetime_mismatch = lifetime mismatch
trait_selection_lifetime_param_suggestion = consider {$is_reuse ->
[true] reusing
*[false] introducing
} a named lifetime parameter{$is_impl ->
[true] {" "}and update trait if needed
*[false] {""}
}
trait_selection_lifetime_param_suggestion_elided = each elided lifetime in input position becomes a distinct lifetime
trait_selection_malformed_on_unimplemented_attr = malformed `on_unimplemented` attribute
.help = only `message`, `note` and `label` are allowed as options
.label = invalid option found here
trait_selection_meant_byte_literal = if you meant to write a byte literal, prefix with `b`
trait_selection_meant_char_literal = if you meant to write a `char` literal, use single quotes
trait_selection_meant_str_literal = if you meant to write a string literal, use double quotes
trait_selection_mismatched_static_lifetime = incompatible lifetime on type
trait_selection_missing_options_for_on_unimplemented_attr = missing options for `on_unimplemented` attribute
.help = at least one of the `message`, `note` and `label` options are expected
trait_selection_msl_introduces_static = introduces a `'static` lifetime requirement
trait_selection_msl_unmet_req = because this has an unmet lifetime requirement
trait_selection_negative_positive_conflict = found both positive and negative implementation of trait `{$trait_desc}`{$self_desc ->
[none] {""}
*[default] {" "}for type `{$self_desc}`
}:
.negative_implementation_here = negative implementation here
.negative_implementation_in_crate = negative implementation in crate `{$negative_impl_cname}`
.positive_implementation_here = positive implementation here
.positive_implementation_in_crate = positive implementation in crate `{$positive_impl_cname}`
trait_selection_nothing = {""}
trait_selection_oc_cant_coerce_force_inline =
cannot coerce functions which must be inlined to function pointers
trait_selection_oc_cant_coerce_intrinsic = cannot coerce intrinsics to function pointers
trait_selection_oc_closure_selfref = closure/coroutine type that references itself
trait_selection_oc_const_compat = const not compatible with trait
trait_selection_oc_fn_lang_correct_type = {$lang_item_name ->
[panic_impl] `#[panic_handler]`
*[lang_item_name] lang item `{$lang_item_name}`
} function has wrong type
trait_selection_oc_fn_main_correct_type = `main` function has wrong type
trait_selection_oc_generic = mismatched types
trait_selection_oc_if_else_different = `if` and `else` have incompatible types
trait_selection_oc_intrinsic_correct_type = intrinsic has wrong type
trait_selection_oc_match_compat = `match` arms have incompatible types
trait_selection_oc_method_compat = method not compatible with trait
trait_selection_oc_method_correct_type = mismatched `self` parameter type
trait_selection_oc_no_diverge = `else` clause of `let...else` does not diverge
trait_selection_oc_no_else = `if` may be missing an `else` clause
trait_selection_oc_try_compat = `?` operator has incompatible types
trait_selection_oc_type_compat = type not compatible with trait
trait_selection_opaque_captures_lifetime = hidden type for `{$opaque_ty}` captures lifetime that does not appear in bounds
.label = opaque type defined here
trait_selection_opaque_type_non_generic_param =
expected generic {$kind} parameter, found `{$arg}`
.label = {STREQ($arg, "'static") ->
[true] cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type
*[other] this generic parameter must be used with a generic {$kind} parameter
}
trait_selection_outlives_bound = lifetime of the source pointer does not outlive lifetime bound of the object type
trait_selection_outlives_content = lifetime of reference outlives lifetime of borrowed content...
trait_selection_precise_capturing_existing = add `{$new_lifetime}` to the `use<...>` bound to explicitly capture it
trait_selection_precise_capturing_new = add a `use<...>` bound to explicitly capture `{$new_lifetime}`
trait_selection_precise_capturing_new_but_apit = add a `use<...>` bound to explicitly capture `{$new_lifetime}` after turning all argument-position `impl Trait` into type parameters, noting that this possibly affects the API of this crate
trait_selection_precise_capturing_overcaptures = use the precise capturing `use<...>` syntax to make the captures explicit
trait_selection_prlf_defined_with_sub = the lifetime `{$sub_symbol}` defined here...
trait_selection_prlf_defined_without_sub = the lifetime defined here...
trait_selection_prlf_known_limitation = this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
trait_selection_prlf_must_outlive_with_sup = ...must outlive the lifetime `{$sup_symbol}` defined here
trait_selection_prlf_must_outlive_without_sup = ...must outlive the lifetime defined here
trait_selection_reborrow = ...so that reference does not outlive borrowed content
trait_selection_ref_longer_than_data = in type `{$ty}`, reference has a longer lifetime than the data it references
trait_selection_reference_outlives_referent = ...so that the reference type `{$name}` does not outlive the data it points at
trait_selection_region_explanation = {$pref_kind ->
*[should_not_happen] [{$pref_kind}]
[ref_valid_for] ...the reference is valid for
[content_valid_for] ...but the borrowed content is only valid for
[type_obj_valid_for] object type is valid for
[source_pointer_valid_for] source pointer is only valid for
[type_satisfy] type must satisfy
[type_outlive] type must outlive
[lf_param_instantiated_with] lifetime parameter instantiated with
[lf_param_must_outlive] but lifetime parameter must outlive
[lf_instantiated_with] lifetime instantiated with
[lf_must_outlive] but lifetime must outlive
[pointer_valid_for] the pointer is valid for
[data_valid_for] but the referenced data is only valid for
[empty] {""}
}{$pref_kind ->
[empty] {""}
*[other] {" "}
}{$desc_kind ->
*[should_not_happen] [{$desc_kind}]
[restatic] the static lifetime
[revar] lifetime {$desc_arg}
[as_defined] the lifetime `{$desc_arg}` as defined here
[as_defined_anon] the anonymous lifetime as defined here
[defined_here] the anonymous lifetime defined here
[defined_here_reg] the lifetime `{$desc_arg}` as defined here
}{$suff_kind ->
*[should_not_happen] [{$suff_kind}]
[empty]{""}
[continues] ...
[req_by_binding] {" "}as required by this binding
}
trait_selection_relate_object_bound = ...so that it can be closed over into an object
trait_selection_relate_param_bound = ...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
[true] ...
*[false] {""}
}
trait_selection_relate_param_bound_2 = ...that is required by this bound
trait_selection_relate_region_param_bound = ...so that the declared lifetime parameter bounds are satisfied
trait_selection_ril_because_of = because of this returned expression
trait_selection_ril_introduced_by = requirement introduced by this return type
trait_selection_ril_introduced_here = `'static` requirement introduced here
trait_selection_ril_static_introduced_by = "`'static` lifetime requirement introduced by the return type
trait_selection_rustc_on_unimplemented_empty_on_clause = empty `on`-clause in `#[rustc_on_unimplemented]`
.label = empty `on`-clause here
trait_selection_rustc_on_unimplemented_expected_identifier = expected an identifier inside this `on`-clause
.label = expected an identifier here, not `{$path}`
trait_selection_rustc_on_unimplemented_expected_one_predicate_in_not = expected a single predicate in `not(..)`
.label = unexpected quantity of predicates here
trait_selection_rustc_on_unimplemented_invalid_flag = invalid flag in `on`-clause
.label = expected one of the `crate_local`, `direct` or `from_desugaring` flags, not `{$invalid_flag}`
trait_selection_rustc_on_unimplemented_invalid_name = invalid name in `on`-clause
.label = expected one of `cause`, `from_desugaring`, `Self` or any generic parameter of the trait, not `{$invalid_name}`
trait_selection_rustc_on_unimplemented_invalid_predicate = this predicate is invalid
.label = expected one of `any`, `all` or `not` here, not `{$invalid_pred}`
trait_selection_rustc_on_unimplemented_missing_value = this attribute must have a value
.label = expected value here
.note = e.g. `#[rustc_on_unimplemented(message="foo")]`
trait_selection_rustc_on_unimplemented_unsupported_literal_in_on = literals inside `on`-clauses are not supported
.label = unexpected literal here
trait_selection_source_kind_closure_return =
try giving this closure an explicit return type
# coroutine_kind may need to be translated
trait_selection_source_kind_fully_qualified =
try using a fully qualified path to specify the expected types
trait_selection_source_kind_subdiag_generic_label =
cannot infer {$is_type ->
[true] type
*[false] the value
} of the {$is_type ->
[true] type
*[false] const
} {$parent_exists ->
[true] parameter `{$param_name}` declared on the {$parent_prefix} `{$parent_name}`
*[false] parameter {$param_name}
}
trait_selection_source_kind_subdiag_generic_suggestion =
consider specifying the generic {$arg_count ->
[one] argument
*[other] arguments
}
trait_selection_source_kind_subdiag_let = {$kind ->
[with_pattern] consider giving `{$name}` an explicit type
[closure] consider giving this closure parameter an explicit type
*[other] consider giving this pattern a type
}{$x_kind ->
[has_name] , where the {$prefix_kind ->
*[type] type for {$prefix}
[const_with_param] value of const parameter
[const] value of the constant
} `{$arg_name}` is specified
[underscore] , where the placeholders `_` are specified
*[empty] {""}
}
trait_selection_srs_add = consider returning the local binding `{$ident}`
trait_selection_srs_add_one = consider returning one of these bindings
trait_selection_srs_remove = consider removing this semicolon
trait_selection_srs_remove_and_box = consider removing this semicolon and boxing the expressions
trait_selection_stp_wrap_many = try wrapping the pattern in a variant of `{$path}`
trait_selection_stp_wrap_one = try wrapping the pattern in `{$variant}`
trait_selection_subtype = ...so that the {$requirement ->
[method_compat] method type is compatible with trait
[type_compat] associated type is compatible with trait
[const_compat] const is compatible with trait
[expr_assignable] expression is assignable
[if_else_different] `if` and `else` have incompatible types
[no_else] `if` missing an `else` returns `()`
[fn_main_correct_type] `main` function has the correct type
[fn_lang_correct_type] lang item function has the correct type
[intrinsic_correct_type] intrinsic has the correct type
[method_correct_type] method receiver has the correct type
*[other] types are compatible
}
trait_selection_subtype_2 = ...so that {$requirement ->
[method_compat] method type is compatible with trait
[type_compat] associated type is compatible with trait
[const_compat] const is compatible with trait
[expr_assignable] expression is assignable
[if_else_different] `if` and `else` have incompatible types
[no_else] `if` missing an `else` returns `()`
[fn_main_correct_type] `main` function has the correct type
[fn_lang_correct_type] lang item function has the correct type
[intrinsic_correct_type] intrinsic has the correct type
[method_correct_type] method receiver has the correct type
*[other] types are compatible
}
trait_selection_suggest_accessing_field = you might have meant to use field `{$name}` whose type is `{$ty}`
trait_selection_suggest_add_let_for_letchains = consider adding `let`
trait_selection_tid_consider_borrowing = consider borrowing this type parameter in the trait
trait_selection_tid_param_help = the lifetime requirements from the `impl` do not correspond to the requirements in the `trait`
trait_selection_tid_rel_help = verify the lifetime relationships in the `trait` and `impl` between the `self` argument, the other inputs and its output
trait_selection_trait_has_no_impls = this trait has no implementations, consider adding one
trait_selection_trait_impl_diff = `impl` item signature doesn't match `trait` item signature
.found = found `{$found}`
.expected = expected `{$expected}`
.expected_found = expected signature `{$expected}`
{" "}found signature `{$found}`
trait_selection_trait_placeholder_mismatch = implementation of `{$trait_def_id}` is not general enough
.label_satisfy = doesn't satisfy where-clause
.label_where = due to a where-clause on `{$def_id}`...
.label_dup = implementation of `{$trait_def_id}` is not general enough
trait_selection_try_cannot_convert = `?` operator cannot convert from `{$found}` to `{$expected}`
trait_selection_tuple_trailing_comma = use a trailing comma to create a tuple with one element
trait_selection_ty_alias_overflow = in case this is a recursive type alias, consider using a struct, enum, or union instead
trait_selection_type_annotations_needed = {$source_kind ->
[closure] type annotations needed for the closure `{$source_name}`
[normal] type annotations needed for `{$source_name}`
*[other] type annotations needed
}
.label = type must be known at this point
trait_selection_types_declared_different = these two types are declared with different lifetimes...
trait_selection_unable_to_construct_constant_value = unable to construct a constant value for the unevaluated constant {$unevaluated}
trait_selection_unknown_format_parameter_for_on_unimplemented_attr = there is no parameter `{$argument_name}` on trait `{$trait_name}`
.help = expect either a generic argument name or {"`{Self}`"} as format argument
trait_selection_warn_removing_apit_params_for_overcapture = you could use a `use<...>` bound to explicitly specify captures, but argument-position `impl Trait`s are not nameable
trait_selection_warn_removing_apit_params_for_undercapture = you could use a `use<...>` bound to explicitly capture `{$new_lifetime}`, but argument-position `impl Trait`s are not nameable
trait_selection_where_copy_predicates = copy the `where` clause predicates from the trait
trait_selection_where_remove = remove the `where` clause
trait_selection_wrapped_parser_error = {$description}
.label = {$label}

View file

@ -2,7 +2,8 @@ use std::iter;
use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{
Applicability, Diag, E0309, E0310, E0311, E0803, Subdiagnostic, struct_span_code_err,
Applicability, Diag, E0309, E0310, E0311, E0803, Subdiagnostic, inline_fluent,
struct_span_code_err,
};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
@ -25,7 +26,6 @@ use crate::errors::{
self, FulfillReqLifetime, LfBoundNotSatisfied, OutlivesBound, OutlivesContent,
RefLongerThanData, RegionOriginNote, WhereClauseSuggestions, note_and_explain,
};
use crate::fluent_generated as fluent;
use crate::infer::region_constraints::GenericKind;
use crate::infer::{
BoundRegionConversionTime, InferCtxt, RegionResolutionError, RegionVariableOrigin,
@ -228,18 +228,22 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
expected_found: self.values_str(trace.values, &trace.cause, err.long_ty_path()),
}
.add_to_diag(err),
SubregionOrigin::Reborrow(span) => {
RegionOriginNote::Plain { span, msg: fluent::trait_selection_reborrow }
.add_to_diag(err)
SubregionOrigin::Reborrow(span) => RegionOriginNote::Plain {
span,
msg: inline_fluent!("...so that reference does not outlive borrowed content"),
}
.add_to_diag(err),
SubregionOrigin::RelateObjectBound(span) => {
RegionOriginNote::Plain { span, msg: fluent::trait_selection_relate_object_bound }
.add_to_diag(err);
RegionOriginNote::Plain {
span,
msg: inline_fluent!("...so that it can be closed over into an object"),
}
.add_to_diag(err);
}
SubregionOrigin::ReferenceOutlivesReferent(ty, span) => {
RegionOriginNote::WithName {
span,
msg: fluent::trait_selection_reference_outlives_referent,
msg: inline_fluent!("...so that the reference type `{$name}` does not outlive the data it points at"),
name: &self.ty_to_string(ty),
continues: false,
}
@ -248,7 +252,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
SubregionOrigin::RelateParamBound(span, ty, opt_span) => {
RegionOriginNote::WithName {
span,
msg: fluent::trait_selection_relate_param_bound,
msg: inline_fluent!("...so that the type `{$name}` will meet its required lifetime bounds{$continues ->
[true] ...
*[false] {\"\"}
}"),
name: &self.ty_to_string(ty),
continues: opt_span.is_some(),
}
@ -256,7 +263,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
if let Some(span) = opt_span {
RegionOriginNote::Plain {
span,
msg: fluent::trait_selection_relate_param_bound_2,
msg: inline_fluent!("...that is required by this bound"),
}
.add_to_diag(err);
}
@ -264,14 +271,18 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
SubregionOrigin::RelateRegionParamBound(span, _) => {
RegionOriginNote::Plain {
span,
msg: fluent::trait_selection_relate_region_param_bound,
msg: inline_fluent!(
"...so that the declared lifetime parameter bounds are satisfied"
),
}
.add_to_diag(err);
}
SubregionOrigin::CompareImplItemObligation { span, .. } => {
RegionOriginNote::Plain {
span,
msg: fluent::trait_selection_compare_impl_item_obligation,
msg: inline_fluent!(
"...so that the definition in impl matches the definition from the trait"
),
}
.add_to_diag(err);
}
@ -281,7 +292,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
SubregionOrigin::AscribeUserTypeProvePredicate(span) => {
RegionOriginNote::Plain {
span,
msg: fluent::trait_selection_ascribe_user_type_prove_predicate,
msg: inline_fluent!("...so that the where clause holds"),
}
.add_to_diag(err);
}

View file

@ -12,7 +12,7 @@ use rustc_data_structures::unord::UnordSet;
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, ErrorGuaranteed, Level, MultiSpan, StashKey, StringPart, Suggestions,
pluralize, struct_span_code_err,
inline_fluent, pluralize, struct_span_code_err,
};
use rustc_hir::def_id::{DefId, LOCAL_CRATE, LocalDefId};
use rustc_hir::intravisit::Visitor;
@ -3003,7 +3003,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
{
err.span_help(
self.tcx.def_span(trait_def_id),
crate::fluent_generated::trait_selection_trait_has_no_impls,
inline_fluent!("this trait has no implementations, consider adding one"),
);
} else if !suggested && trait_predicate.polarity() == ty::PredicatePolarity::Positive {
// Can't show anything else useful, try to find similar impls.

View file

@ -360,10 +360,10 @@ pub enum AppendConstMessage {
}
#[derive(LintDiagnostic)]
#[diag(trait_selection_malformed_on_unimplemented_attr)]
#[help]
#[diag("malformed `on_unimplemented` attribute")]
#[help("only `message`, `note` and `label` are allowed as options")]
pub struct MalformedOnUnimplementedAttrLint {
#[label]
#[label("invalid option found here")]
pub span: Span,
}
@ -374,17 +374,17 @@ impl MalformedOnUnimplementedAttrLint {
}
#[derive(LintDiagnostic)]
#[diag(trait_selection_missing_options_for_on_unimplemented_attr)]
#[help]
#[diag("missing options for `on_unimplemented` attribute")]
#[help("at least one of the `message`, `note` and `label` options are expected")]
pub struct MissingOptionsForOnUnimplementedAttr;
#[derive(LintDiagnostic)]
#[diag(trait_selection_ignored_diagnostic_option)]
#[diag("`{$option_name}` is ignored due to previous definition of `{$option_name}`")]
pub struct IgnoredDiagnosticOption {
pub option_name: &'static str,
#[label]
#[label("`{$option_name}` is already declared here")]
pub span: Span,
#[label(trait_selection_other_label)]
#[label("`{$option_name}` is first declared here")]
pub prev_span: Span,
}
@ -410,7 +410,7 @@ impl IgnoredDiagnosticOption {
}
#[derive(LintDiagnostic)]
#[diag(trait_selection_wrapped_parser_error)]
#[diag("{$description}")]
pub struct WrappedParserError {
pub description: String,
pub label: String,

View file

@ -310,25 +310,27 @@ pub mod errors {
use super::*;
#[derive(LintDiagnostic)]
#[diag(trait_selection_unknown_format_parameter_for_on_unimplemented_attr)]
#[help]
#[diag("there is no parameter `{$argument_name}` on trait `{$trait_name}`")]
#[help("expect either a generic argument name or {\"`{Self}`\"} as format argument")]
pub struct UnknownFormatParameterForOnUnimplementedAttr {
pub argument_name: Symbol,
pub trait_name: Ident,
}
#[derive(LintDiagnostic)]
#[diag(trait_selection_disallowed_positional_argument)]
#[help]
#[diag("positional format arguments are not allowed here")]
#[help(
"only named format arguments with the name of one of the generic types are allowed in this context"
)]
pub struct DisallowedPositionalArgument;
#[derive(LintDiagnostic)]
#[diag(trait_selection_invalid_format_specifier)]
#[help]
#[diag("invalid format specifier")]
#[help("no format specifier are supported in this position")]
pub struct InvalidFormatSpecifier;
#[derive(LintDiagnostic)]
#[diag(trait_selection_missing_options_for_on_unimplemented_attr)]
#[help]
#[diag("missing options for `on_unimplemented` attribute")]
#[help("at least one of the `message`, `note` and `label` options are expected")]
pub struct MissingOptionsForOnUnimplementedAttr;
}

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,10 @@
use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, Subdiagnostic};
use rustc_errors::{Diag, EmissionGuarantee, IntoDiagArg, Subdiagnostic, inline_fluent};
use rustc_hir::def_id::LocalDefId;
use rustc_middle::bug;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::{Span, kw};
use crate::error_reporting::infer::nice_region_error::find_anon_type;
use crate::fluent_generated as fluent;
struct DescriptionCtx<'a> {
span: Option<Span>,
@ -170,7 +169,40 @@ impl Subdiagnostic for RegionExplanation<'_> {
diag.arg("desc_kind", self.desc.kind);
diag.arg("desc_arg", self.desc.arg);
let msg = diag.eagerly_translate(fluent::trait_selection_region_explanation);
let msg = diag.eagerly_translate(inline_fluent!(
"{$pref_kind ->
*[should_not_happen] [{$pref_kind}]
[ref_valid_for] ...the reference is valid for
[content_valid_for] ...but the borrowed content is only valid for
[type_obj_valid_for] object type is valid for
[source_pointer_valid_for] source pointer is only valid for
[type_satisfy] type must satisfy
[type_outlive] type must outlive
[lf_param_instantiated_with] lifetime parameter instantiated with
[lf_param_must_outlive] but lifetime parameter must outlive
[lf_instantiated_with] lifetime instantiated with
[lf_must_outlive] but lifetime must outlive
[pointer_valid_for] the pointer is valid for
[data_valid_for] but the referenced data is only valid for
[empty] {\"\"}
}{$pref_kind ->
[empty] {\"\"}
*[other] {\" \"}
}{$desc_kind ->
*[should_not_happen] [{$desc_kind}]
[restatic] the static lifetime
[revar] lifetime {$desc_arg}
[as_defined] the lifetime `{$desc_arg}` as defined here
[as_defined_anon] the anonymous lifetime as defined here
[defined_here] the anonymous lifetime defined here
[defined_here_reg] the lifetime `{$desc_arg}` as defined here
}{$suff_kind ->
*[should_not_happen] [{$suff_kind}]
[empty]{\"\"}
[continues] ...
[req_by_binding] {\" \"}as required by this binding
}"
));
diag.restore_args();
if let Some(span) = self.desc.span {
diag.span_note(span, msg);

View file

@ -34,5 +34,3 @@ pub mod opaque_types;
pub mod regions;
pub mod solve;
pub mod traits;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -7,10 +7,9 @@
use std::ops::ControlFlow;
use rustc_errors::FatalError;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem, find_attr};
use rustc_hir::{self as hir, LangItem};
use rustc_middle::query::Providers;
use rustc_middle::ty::{
self, EarlyBinder, GenericArgs, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
@ -333,7 +332,7 @@ pub fn dyn_compatibility_violations_for_assoc_item(
if tcx.features().min_generic_const_args() {
if !tcx.generics_of(item.def_id).is_own_empty() {
errors.push(AssocConstViolation::Generic);
} else if !find_attr!(tcx.get_all_attrs(item.def_id), AttributeKind::TypeConst(_)) {
} else if !tcx.is_type_const(item.def_id) {
errors.push(AssocConstViolation::NonType);
}

View file

@ -1,6 +1,7 @@
//! Deeply normalize types using the old trait solver.
use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::inline_fluent;
use rustc_hir::def::DefKind;
use rustc_infer::infer::at::At;
use rustc_infer::infer::{InferCtxt, InferOk};
@ -294,7 +295,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
self.cause.span,
false,
|diag| {
diag.note(crate::fluent_generated::trait_selection_ty_alias_overflow);
diag.note(inline_fluent!("in case this is a recursive type alias, consider using a struct, enum, or union instead"));
},
);
}

View file

@ -1008,33 +1008,9 @@ impl Step for OmpOffload {
t!(fs::create_dir_all(&out_dir));
builder.config.update_submodule("src/llvm-project");
let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/runtimes/"));
// If we use an external clang as opposed to building our own llvm_clang, than that clang will
// come with it's own set of default include directories, which are based on a potentially older
// LLVM. This can cause issues, so we overwrite it to include headers based on our
// `src/llvm-project` submodule instead.
// FIXME(offload): With LLVM-22 we hopefully won't need an external clang anymore.
let mut cflags = CcFlags::default();
if !builder.config.llvm_clang {
let base = builder.llvm_out(target).join("include");
let inc_dir = base.display();
cflags.push_all(format!(" -I {inc_dir}"));
}
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), cflags, &[]);
// Re-use the same flags as llvm to control the level of debug information
// generated for offload.
let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
(false, _) => "Debug",
(true, false) => "Release",
(true, true) => "RelWithDebInfo",
};
trace!(?profile);
// OpenMP/Offload builds currently (LLVM-21) still depend on Clang, although there are
// intentions to loosen this requirement for LLVM-22. If we were to
// OpenMP/Offload builds currently (LLVM-22) still depend on Clang, although there are
// intentions to loosen this requirement over time. FIXME(offload): re-evaluate on LLVM 23
let clang_dir = if !builder.config.llvm_clang {
// We must have an external clang to use.
assert!(&builder.build.config.llvm_clang_dir.is_some());
@ -1044,23 +1020,66 @@ impl Step for OmpOffload {
None
};
// FIXME(offload): Once we move from OMP to Offload (Ol) APIs, we should drop the openmp
// runtime to simplify our build. We should also re-evaluate the LLVM_Root and try to get
// rid of the Clang_DIR, once we upgrade to LLVM-22.
cfg.out_dir(&out_dir)
.profile(profile)
.env("LLVM_CONFIG_REAL", &host_llvm_config)
.define("LLVM_ENABLE_ASSERTIONS", "ON")
.define("LLVM_ENABLE_RUNTIMES", "openmp;offload")
.define("LLVM_INCLUDE_TESTS", "OFF")
.define("OFFLOAD_INCLUDE_TESTS", "OFF")
.define("OPENMP_STANDALONE_BUILD", "ON")
.define("LLVM_ROOT", builder.llvm_out(target).join("build"))
.define("LLVM_DIR", llvm_cmake_dir);
if let Some(p) = clang_dir {
cfg.define("Clang_DIR", p);
// In the context of OpenMP offload, some libraries must be compiled for the gpu target,
// some for the host, and others for both. We do not perform a full cross-compilation, since
// we don't want to run rustc on a GPU.
let omp_targets = vec![target.triple.as_ref(), "amdgcn-amd-amdhsa", "nvptx64-nvidia-cuda"];
for omp_target in omp_targets {
let mut cfg = cmake::Config::new(builder.src.join("src/llvm-project/runtimes/"));
// If we use an external clang as opposed to building our own llvm_clang, than that clang will
// come with it's own set of default include directories, which are based on a potentially older
// LLVM. This can cause issues, so we overwrite it to include headers based on our
// `src/llvm-project` submodule instead.
// FIXME(offload): With LLVM-22 we hopefully won't need an external clang anymore.
let mut cflags = CcFlags::default();
if !builder.config.llvm_clang {
let base = builder.llvm_out(target).join("include");
let inc_dir = base.display();
cflags.push_all(format!(" -I {inc_dir}"));
}
configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), cflags, &[]);
// Re-use the same flags as llvm to control the level of debug information
// generated for offload.
let profile =
match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
(false, _) => "Debug",
(true, false) => "Release",
(true, true) => "RelWithDebInfo",
};
trace!(?profile);
// FIXME(offload): Once we move from OMP to Offload (Ol) APIs, we should drop the openmp
// runtime to simplify our build. So far, these are still under development.
cfg.out_dir(&out_dir)
.profile(profile)
.env("LLVM_CONFIG_REAL", &host_llvm_config)
.define("LLVM_ENABLE_ASSERTIONS", "ON")
.define("LLVM_INCLUDE_TESTS", "OFF")
.define("OFFLOAD_INCLUDE_TESTS", "OFF")
.define("LLVM_ROOT", builder.llvm_out(target).join("build"))
.define("LLVM_DIR", llvm_cmake_dir.clone())
.define("LLVM_DEFAULT_TARGET_TRIPLE", omp_target);
if let Some(p) = clang_dir.clone() {
cfg.define("Clang_DIR", p);
}
// We don't perform a full cross-compilation of rustc, therefore our target.triple
// will still be a CPU target.
if *omp_target == *target.triple {
// The offload library provides functionality which only makes sense on the host.
cfg.define("LLVM_ENABLE_RUNTIMES", "openmp;offload");
} else {
// OpenMP provides some device libraries, so we also compile it for all gpu targets.
cfg.define("LLVM_USE_LINKER", "lld");
cfg.define("LLVM_ENABLE_RUNTIMES", "openmp");
cfg.define("CMAKE_C_COMPILER_TARGET", omp_target);
cfg.define("CMAKE_CXX_COMPILER_TARGET", omp_target);
}
cfg.build();
}
cfg.build();
t!(stamp.write());

View file

@ -4,14 +4,12 @@
extern crate rustc_driver;
extern crate rustc_error_codes;
extern crate rustc_errors;
extern crate rustc_hash;
extern crate rustc_hir;
extern crate rustc_interface;
extern crate rustc_session;
extern crate rustc_span;
use rustc_errors::registry;
use rustc_hash::FxHashMap;
use rustc_session::config;
@ -50,8 +48,6 @@ fn main() {
//
// The second parameter is local providers and the third parameter is external providers.
override_queries: None, // Option<fn(&Session, &mut ty::query::Providers<'_>, &mut ty::query::Providers<'_>)>
// Registry of diagnostics codes.
registry: registry::Registry::new(rustc_errors::codes::DIAGNOSTICS),
make_codegen_backend: None,
expanded_args: Vec::new(),
ice_file: None,

View file

@ -15,7 +15,7 @@ extern crate rustc_span;
use std::sync::{Arc, Mutex};
use rustc_errors::emitter::Emitter;
use rustc_errors::registry::{self, Registry};
use rustc_errors::registry::Registry;
use rustc_errors::translation::Translate;
use rustc_errors::{DiagInner, FluentBundle};
use rustc_session::config;
@ -76,7 +76,6 @@ fn main() {
})),
register_lints: None,
override_queries: None,
registry: registry::Registry::new(rustc_errors::codes::DIAGNOSTICS),
make_codegen_backend: None,
expanded_args: Vec::new(),
ice_file: None,

View file

@ -3,7 +3,7 @@
**Tier: 2 (without Host Tools)**
RISC-V target using the ratified [RVA23 Profile](https://github.com/riscv/riscv-profiles/blob/main/src/rva23-profile.adoc).
This target will enable all mandary features of rva23u64 by default.
This target will enable all mandatory features of rva23u64 by default.
## Target maintainers
@ -14,7 +14,7 @@ This target will enable all mandary features of rva23u64 by default.
This target can be sucessfully build on the following platform: ubuntu 24.04 (Linux Kernel version 6.8.0, glibc 2.39).
Other platforms may work, but are not tested. Please contanct if you encounter any issues.
Other platforms may work, but are not tested. Please contact us if you encounter any issues.
## Building the target

View file

@ -322,7 +322,6 @@ pub(crate) fn create_config(
}),
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
ice_file: None,
using_internal_features: &USING_INTERNAL_FEATURES,
}

View file

@ -196,7 +196,6 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions
override_queries: None,
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
ice_file: None,
using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES,
};

View file

@ -5,7 +5,6 @@ use std::sync::Arc;
use rustc_data_structures::sync::Lock;
use rustc_errors::emitter::Emitter;
use rustc_errors::registry::Registry;
use rustc_errors::translation::{Translator, to_fluent_args};
use rustc_errors::{Applicability, DiagCtxt, DiagInner};
use rustc_parse::{source_str_to_stream, unwrap_or_emit_fatal};
@ -150,7 +149,7 @@ struct BufferEmitter {
}
impl Emitter for BufferEmitter {
fn emit_diagnostic(&mut self, diag: DiagInner, _registry: &Registry) {
fn emit_diagnostic(&mut self, diag: DiagInner) {
let mut buffer = self.buffer.borrow_mut();
let fluent_args = to_fluent_args(diag.args.iter());

View file

@ -1,10 +1,11 @@
#![feature(rustc_private)]
extern crate rustc_driver;
extern crate rustc_error_codes;
extern crate rustc_errors;
extern crate rustc_log;
extern crate rustc_session;
extern crate rustc_errors;
use std::env;
use std::error::Error;
use std::fs::{self, File};
@ -16,7 +17,22 @@ use mdbook_driver::MDBook;
use mdbook_driver::book::{BookItem, Chapter};
use mdbook_driver::config::Config;
use mdbook_summary::parse_summary;
use rustc_errors::codes::DIAGNOSTICS;
use rustc_errors::codes::ErrCode;
macro_rules! define_error_codes_table {
($($num:literal,)*) => (
static DIAGNOSTICS: &[(ErrCode, &str)] = &[
$( (
ErrCode::from_u32($num),
include_str!(
concat!("../../../compiler/rustc_error_codes/src/error_codes/E", stringify!($num), ".md")
)
), )*
];
)
}
rustc_error_codes::error_codes!(define_error_codes_table);
enum OutputFormat {
HTML,

View file

@ -5,7 +5,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
use rustc_data_structures::sync::IntoDynSyncSend;
use rustc_errors::annotate_snippet_emitter_writer::AnnotateSnippetEmitter;
use rustc_errors::emitter::{DynEmitter, Emitter, SilentEmitter, stderr_destination};
use rustc_errors::registry::Registry;
use rustc_errors::translation::Translator;
use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel};
use rustc_session::parse::ParseSess as RawParseSess;
@ -41,10 +40,10 @@ struct SilentOnIgnoredFilesEmitter {
}
impl SilentOnIgnoredFilesEmitter {
fn handle_non_ignoreable_error(&mut self, diag: DiagInner, registry: &Registry) {
fn handle_non_ignoreable_error(&mut self, diag: DiagInner) {
self.has_non_ignorable_parser_errors = true;
self.can_reset.store(false, Ordering::Release);
self.emitter.emit_diagnostic(diag, registry);
self.emitter.emit_diagnostic(diag);
}
}
@ -53,9 +52,9 @@ impl Emitter for SilentOnIgnoredFilesEmitter {
None
}
fn emit_diagnostic(&mut self, diag: DiagInner, registry: &Registry) {
fn emit_diagnostic(&mut self, diag: DiagInner) {
if diag.level() == DiagnosticLevel::Fatal {
return self.handle_non_ignoreable_error(diag, registry);
return self.handle_non_ignoreable_error(diag);
}
if let Some(primary_span) = &diag.span.primary_span() {
let file_name = self.source_map.span_to_filename(*primary_span);
@ -73,7 +72,7 @@ impl Emitter for SilentOnIgnoredFilesEmitter {
}
}
}
self.handle_non_ignoreable_error(diag, registry);
self.handle_non_ignoreable_error(diag);
}
fn translator(&self) -> &Translator {
@ -340,7 +339,7 @@ mod tests {
None
}
fn emit_diagnostic(&mut self, _diag: DiagInner, _registry: &Registry) {
fn emit_diagnostic(&mut self, _diag: DiagInner) {
self.num_emitted_errors.fetch_add(1, Ordering::Release);
}
@ -401,7 +400,6 @@ mod tests {
let source =
String::from(r#"extern "system" fn jni_symbol!( funcName ) ( ... ) -> {} "#);
source_map.new_source_file(filename(&source_map, "foo.rs"), source);
let registry = Registry::new(&[]);
let mut emitter = build_emitter(
Arc::clone(&num_emitted_errors),
Arc::clone(&can_reset_errors),
@ -410,7 +408,7 @@ mod tests {
);
let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, Some(span));
emitter.emit_diagnostic(fatal_diagnostic, &registry);
emitter.emit_diagnostic(fatal_diagnostic);
assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1);
assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
}
@ -424,7 +422,6 @@ mod tests {
let source_map = Arc::new(SourceMap::new(FilePathMapping::empty()));
let source = String::from(r#"pub fn bar() { 1x; }"#);
source_map.new_source_file(filename(&source_map, "foo.rs"), source);
let registry = Registry::new(&[]);
let mut emitter = build_emitter(
Arc::clone(&num_emitted_errors),
Arc::clone(&can_reset_errors),
@ -433,7 +430,7 @@ mod tests {
);
let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
emitter.emit_diagnostic(non_fatal_diagnostic, &registry);
emitter.emit_diagnostic(non_fatal_diagnostic);
assert_eq!(num_emitted_errors.load(Ordering::Acquire), 0);
assert_eq!(can_reset_errors.load(Ordering::Acquire), true);
}
@ -446,7 +443,6 @@ mod tests {
let source_map = Arc::new(SourceMap::new(FilePathMapping::empty()));
let source = String::from(r#"pub fn bar() { 1x; }"#);
source_map.new_source_file(filename(&source_map, "foo.rs"), source);
let registry = Registry::new(&[]);
let mut emitter = build_emitter(
Arc::clone(&num_emitted_errors),
Arc::clone(&can_reset_errors),
@ -455,7 +451,7 @@ mod tests {
);
let span = MultiSpan::from_span(mk_sp(BytePos(0), BytePos(1)));
let non_fatal_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(span));
emitter.emit_diagnostic(non_fatal_diagnostic, &registry);
emitter.emit_diagnostic(non_fatal_diagnostic);
assert_eq!(num_emitted_errors.load(Ordering::Acquire), 1);
assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
}
@ -474,7 +470,6 @@ mod tests {
source_map.new_source_file(filename(&source_map, "bar.rs"), bar_source);
source_map.new_source_file(filename(&source_map, "foo.rs"), foo_source);
source_map.new_source_file(filename(&source_map, "fatal.rs"), fatal_source);
let registry = Registry::new(&[]);
let mut emitter = build_emitter(
Arc::clone(&num_emitted_errors),
Arc::clone(&can_reset_errors),
@ -486,9 +481,9 @@ mod tests {
let bar_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(bar_span));
let foo_diagnostic = build_diagnostic(DiagnosticLevel::Warning, Some(foo_span));
let fatal_diagnostic = build_diagnostic(DiagnosticLevel::Fatal, None);
emitter.emit_diagnostic(bar_diagnostic, &registry);
emitter.emit_diagnostic(foo_diagnostic, &registry);
emitter.emit_diagnostic(fatal_diagnostic, &registry);
emitter.emit_diagnostic(bar_diagnostic);
emitter.emit_diagnostic(foo_diagnostic);
emitter.emit_diagnostic(fatal_diagnostic);
assert_eq!(num_emitted_errors.load(Ordering::Acquire), 2);
assert_eq!(can_reset_errors.load(Ordering::Acquire), false);
}

View file

@ -302,7 +302,7 @@ fn deny_new_nondescriptive_test_names(
&& !stripped_path.starts_with("ui/issues/")
{
check.error(format!(
"file `tests/{stripped_path}` must begin with a descriptive name, consider `{{reason}}-issue-{issue_n}.rs`",
"issue-number-only test names are not descriptive, consider renaming file `tests/{stripped_path}` to `{{reason}}-issue-{issue_n}.rs`",
issue_n = &test_name[1],
));
}

View file

@ -72,7 +72,6 @@ fn compile(code: String, output: PathBuf, sysroot: Sysroot, linker: Option<&Path
override_queries: None,
extra_symbols: Vec::new(),
make_codegen_backend: None,
registry: rustc_driver::diagnostics_registry(),
using_internal_features: &rustc_driver::USING_INTERNAL_FEATURES,
};

View file

@ -1,3 +1,36 @@
error: `#[rustc_abi]` attribute cannot be used on constants
--> $DIR/debug.rs:42:1
|
LL | #[rustc_abi(debug)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_abi]` can be applied to functions and type aliases
error: `#[rustc_abi]` attribute cannot be used on associated consts
--> $DIR/debug.rs:46:5
|
LL | #[rustc_abi(debug)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_abi]` can be applied to functions and type aliases
error[E0539]: malformed `rustc_abi` attribute input
--> $DIR/debug.rs:74:1
|
LL | #[rustc_abi("assert_eq")]
| ^^^^^^^^^^^-------------^
| |
| valid arguments are `assert_eq` or `debug`
|
help: try changing it to one of the following valid forms of the attribute
|
LL - #[rustc_abi("assert_eq")]
LL + #[rustc_abi(assert_eq)]
|
LL - #[rustc_abi("assert_eq")]
LL + #[rustc_abi(debug)]
|
error: fn_abi_of(test) = FnAbi {
args: [
ArgAbi {
@ -884,12 +917,6 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
= help: the trait `Sized` is not implemented for `str`
= note: only the last element of a tuple may have a dynamically sized type
error: unrecognized argument
--> $DIR/debug.rs:74:13
|
LL | #[rustc_abi("assert_eq")]
| ^^^^^^^^^^^
error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
--> $DIR/debug.rs:47:5
|
@ -986,6 +1013,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
LL | fn assoc_test(&self) {}
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 12 previous errors
error: aborting due to 14 previous errors
For more information about this error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0277, E0539.
For more information about an error, try `rustc --explain E0277`.

View file

@ -1,3 +1,36 @@
error: `#[rustc_abi]` attribute cannot be used on constants
--> $DIR/debug.rs:42:1
|
LL | #[rustc_abi(debug)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_abi]` can be applied to functions and type aliases
error: `#[rustc_abi]` attribute cannot be used on associated consts
--> $DIR/debug.rs:46:5
|
LL | #[rustc_abi(debug)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_abi]` can be applied to functions and type aliases
error[E0539]: malformed `rustc_abi` attribute input
--> $DIR/debug.rs:74:1
|
LL | #[rustc_abi("assert_eq")]
| ^^^^^^^^^^^-------------^
| |
| valid arguments are `assert_eq` or `debug`
|
help: try changing it to one of the following valid forms of the attribute
|
LL - #[rustc_abi("assert_eq")]
LL + #[rustc_abi(assert_eq)]
|
LL - #[rustc_abi("assert_eq")]
LL + #[rustc_abi(debug)]
|
error: fn_abi_of(test) = FnAbi {
args: [
ArgAbi {
@ -884,12 +917,6 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
= help: the trait `Sized` is not implemented for `str`
= note: only the last element of a tuple may have a dynamically sized type
error: unrecognized argument
--> $DIR/debug.rs:74:13
|
LL | #[rustc_abi("assert_eq")]
| ^^^^^^^^^^^
error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
--> $DIR/debug.rs:47:5
|
@ -986,6 +1013,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
LL | fn assoc_test(&self) {}
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 12 previous errors
error: aborting due to 14 previous errors
For more information about this error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0277, E0539.
For more information about an error, try `rustc --explain E0277`.

View file

@ -1,3 +1,36 @@
error: `#[rustc_abi]` attribute cannot be used on constants
--> $DIR/debug.rs:42:1
|
LL | #[rustc_abi(debug)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_abi]` can be applied to functions and type aliases
error: `#[rustc_abi]` attribute cannot be used on associated consts
--> $DIR/debug.rs:46:5
|
LL | #[rustc_abi(debug)]
| ^^^^^^^^^^^^^^^^^^^
|
= help: `#[rustc_abi]` can be applied to functions and type aliases
error[E0539]: malformed `rustc_abi` attribute input
--> $DIR/debug.rs:74:1
|
LL | #[rustc_abi("assert_eq")]
| ^^^^^^^^^^^-------------^
| |
| valid arguments are `assert_eq` or `debug`
|
help: try changing it to one of the following valid forms of the attribute
|
LL - #[rustc_abi("assert_eq")]
LL + #[rustc_abi(assert_eq)]
|
LL - #[rustc_abi("assert_eq")]
LL + #[rustc_abi(debug)]
|
error: fn_abi_of(test) = FnAbi {
args: [
ArgAbi {
@ -884,12 +917,6 @@ LL | type TestAbiEqNonsense = (fn((str, str)), fn((str, str)));
= help: the trait `Sized` is not implemented for `str`
= note: only the last element of a tuple may have a dynamically sized type
error: unrecognized argument
--> $DIR/debug.rs:74:13
|
LL | #[rustc_abi("assert_eq")]
| ^^^^^^^^^^^
error: `#[rustc_abi]` can only be applied to function items, type aliases, and associated functions
--> $DIR/debug.rs:47:5
|
@ -986,6 +1013,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
LL | fn assoc_test(&self) {}
| ^^^^^^^^^^^^^^^^^^^^
error: aborting due to 12 previous errors
error: aborting due to 14 previous errors
For more information about this error, try `rustc --explain E0277`.
Some errors have detailed explanations: E0277, E0539.
For more information about an error, try `rustc --explain E0277`.

View file

@ -39,12 +39,12 @@ type TestFnPtr = fn(bool) -> u8; //~ ERROR: fn_abi
#[rustc_abi(debug)]
fn test_generic<T>(_x: *const T) {} //~ ERROR: fn_abi
#[rustc_abi(debug)]
const C: () = (); //~ ERROR: can only be applied to
#[rustc_abi(debug)] //~ ERROR: `#[rustc_abi]` attribute cannot be used on constants
const C: () = (); //~ ERROR: `#[rustc_abi]` can only be applied to
impl S {
#[rustc_abi(debug)]
const C: () = (); //~ ERROR: can only be applied to
#[rustc_abi(debug)] //~ ERROR: `#[rustc_abi]` attribute cannot be used on assoc
const C: () = (); //~ ERROR: `#[rustc_abi]` can only be applied to
}
impl S {
@ -71,5 +71,5 @@ type TestAbiNeSign = (fn(i32), fn(u32)); //~ ERROR: ABIs are not compatible
#[rustc_abi(assert_eq)]
type TestAbiEqNonsense = (fn((str, str)), fn((str, str))); //~ ERROR: cannot be known at compilation time
#[rustc_abi("assert_eq")] //~ ERROR unrecognized argument
#[rustc_abi("assert_eq")] //~ ERROR malformed `rustc_abi` attribute input
type Bad = u32;

View file

@ -795,7 +795,8 @@ zulip_stream = 474880 # #t-compiler/backports
topic = "#{number}: stable-nominated"
message_on_add = [
"""\
@**channel** PR #{number} "{title}" has been nominated for stable backport.
PR #{number} "{title}" fixes a regression and has been nominated for backport.
{recipients}, what do you think about it?
""",
"""\
/poll Approve stable backport of #{number}?