Split diagnostic details out into a separate function and fluent files
This commit is contained in:
parent
8286ea5a49
commit
1c26a278f3
4 changed files with 57 additions and 26 deletions
|
@ -137,3 +137,12 @@ hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(l
|
||||||
hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
|
hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
|
||||||
|
|
||||||
hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function
|
hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function
|
||||||
|
|
||||||
|
hir_analysis_const_impl_for_non_const_trait =
|
||||||
|
const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]`
|
||||||
|
.suggestion = mark `{$trait_name}` as const
|
||||||
|
.note = marking a trait with `#[const_trait]` 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_bound_for_non_const_trait =
|
||||||
|
~const can only be applied to `#[const_trait]` traits
|
||||||
|
|
|
@ -539,10 +539,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
if let Some(ty::BoundConstness::ConstIfConst) = constness
|
if let Some(ty::BoundConstness::ConstIfConst) = constness
|
||||||
&& generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
|
&& generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
|
||||||
{
|
{
|
||||||
tcx.sess.span_err(
|
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
|
||||||
span,
|
|
||||||
"~const can only be applied to `#[const_trait]` traits",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(substs, arg_count)
|
(substs, arg_count)
|
||||||
|
|
|
@ -1294,34 +1294,38 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
|
||||||
&icx,
|
&icx,
|
||||||
ast_trait_ref,
|
ast_trait_ref,
|
||||||
selfty,
|
selfty,
|
||||||
match impl_.constness {
|
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
|
||||||
hir::Constness::Const => {
|
|
||||||
if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
|
|
||||||
let trait_name = tcx.item_name(trait_def_id);
|
|
||||||
let mut err = tcx.sess.struct_span_err(
|
|
||||||
ast_trait_ref.path.span,
|
|
||||||
&format!("const `impl` for trait `{trait_name}` which is not marked with `#[const_trait]`"),
|
|
||||||
);
|
|
||||||
if trait_def_id.is_local() {
|
|
||||||
let sp = tcx.def_span(trait_def_id).shrink_to_lo();
|
|
||||||
err.span_suggestion(sp, &format!("mark `{trait_name}` as const"), "#[const_trait]", rustc_errors::Applicability::MachineApplicable);
|
|
||||||
}
|
|
||||||
err.note("marking a trait with `#[const_trait]` ensures all default method bodies are `const`");
|
|
||||||
err.note("adding a non-const method body in the future would be a breaking change");
|
|
||||||
err.emit();
|
|
||||||
ty::BoundConstness::NotConst
|
|
||||||
} else {
|
|
||||||
ty::BoundConstness::ConstIfConst
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hir::Constness::NotConst => ty::BoundConstness::NotConst,
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn check_impl_constness(
|
||||||
|
tcx: TyCtxt<'_>,
|
||||||
|
constness: hir::Constness,
|
||||||
|
ast_trait_ref: &hir::TraitRef<'_>,
|
||||||
|
) -> ty::BoundConstness {
|
||||||
|
match constness {
|
||||||
|
hir::Constness::Const => {
|
||||||
|
if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
|
||||||
|
let trait_name = tcx.item_name(trait_def_id).to_string();
|
||||||
|
tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
|
||||||
|
trait_ref_span: ast_trait_ref.path.span,
|
||||||
|
trait_name,
|
||||||
|
local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
|
||||||
|
marking: (),
|
||||||
|
adding: (),
|
||||||
|
});
|
||||||
|
ty::BoundConstness::NotConst
|
||||||
|
} else {
|
||||||
|
ty::BoundConstness::ConstIfConst
|
||||||
|
}
|
||||||
|
},
|
||||||
|
hir::Constness::NotConst => ty::BoundConstness::NotConst,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
|
fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
|
||||||
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
|
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
|
||||||
let item = tcx.hir().expect_item(def_id.expect_local());
|
let item = tcx.hir().expect_item(def_id.expect_local());
|
||||||
|
|
|
@ -249,3 +249,24 @@ pub struct ExpectedUsedSymbol {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_const_impl_for_non_const_trait)]
|
||||||
|
pub struct ConstImplForNonConstTrait {
|
||||||
|
#[primary_span]
|
||||||
|
pub trait_ref_span: Span,
|
||||||
|
pub trait_name: String,
|
||||||
|
#[suggestion(applicability = "machine-applicable", code = "#[const_trait]")]
|
||||||
|
pub local_trait_span: Option<Span>,
|
||||||
|
#[note]
|
||||||
|
pub marking: (),
|
||||||
|
#[note(adding)]
|
||||||
|
pub adding: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Diagnostic)]
|
||||||
|
#[diag(hir_analysis_const_bound_for_non_const_trait)]
|
||||||
|
pub struct ConstBoundForNonConstTrait {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue