Skip to content

Commit 1c26a27

Browse files
committed
Split diagnostic details out into a separate function and fluent files
1 parent 8286ea5 commit 1c26a27

File tree

4 files changed

+57
-26
lines changed

4 files changed

+57
-26
lines changed

compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl

+9
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,12 @@ hir_analysis_expected_used_symbol = expected `used`, `used(compiler)` or `used(l
137137
hir_analysis_missing_parentheses_in_range = can't call method `{$method_name}` on type `{$ty_str}`
138138
139139
hir_analysis_add_missing_parentheses_in_range = you must surround the range in parentheses to call its `{$func_name}` function
140+
141+
hir_analysis_const_impl_for_non_const_trait =
142+
const `impl` for trait `{$trait_name}` which is not marked with `#[const_trait]`
143+
.suggestion = mark `{$trait_name}` as const
144+
.note = marking a trait with `#[const_trait]` ensures all default method bodies are `const`
145+
.adding = adding a non-const method body in the future would be a breaking change
146+
147+
hir_analysis_const_bound_for_non_const_trait =
148+
~const can only be applied to `#[const_trait]` traits

compiler/rustc_hir_analysis/src/astconv/mod.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -539,10 +539,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
539539
if let Some(ty::BoundConstness::ConstIfConst) = constness
540540
&& generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
541541
{
542-
tcx.sess.span_err(
543-
span,
544-
"~const can only be applied to `#[const_trait]` traits",
545-
);
542+
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
546543
}
547544

548545
(substs, arg_count)

compiler/rustc_hir_analysis/src/collect.rs

+26-22
Original file line numberDiff line numberDiff line change
@@ -1294,34 +1294,38 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
12941294
&icx,
12951295
ast_trait_ref,
12961296
selfty,
1297-
match impl_.constness {
1298-
hir::Constness::Const => {
1299-
if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
1300-
let trait_name = tcx.item_name(trait_def_id);
1301-
let mut err = tcx.sess.struct_span_err(
1302-
ast_trait_ref.path.span,
1303-
&format!("const `impl` for trait `{trait_name}` which is not marked with `#[const_trait]`"),
1304-
);
1305-
if trait_def_id.is_local() {
1306-
let sp = tcx.def_span(trait_def_id).shrink_to_lo();
1307-
err.span_suggestion(sp, &format!("mark `{trait_name}` as const"), "#[const_trait]", rustc_errors::Applicability::MachineApplicable);
1308-
}
1309-
err.note("marking a trait with `#[const_trait]` ensures all default method bodies are `const`");
1310-
err.note("adding a non-const method body in the future would be a breaking change");
1311-
err.emit();
1312-
ty::BoundConstness::NotConst
1313-
} else {
1314-
ty::BoundConstness::ConstIfConst
1315-
}
1316-
},
1317-
hir::Constness::NotConst => ty::BoundConstness::NotConst,
1318-
},
1297+
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
13191298
)
13201299
}),
13211300
_ => bug!(),
13221301
}
13231302
}
13241303

1304+
fn check_impl_constness(
1305+
tcx: TyCtxt<'_>,
1306+
constness: hir::Constness,
1307+
ast_trait_ref: &hir::TraitRef<'_>,
1308+
) -> ty::BoundConstness {
1309+
match constness {
1310+
hir::Constness::Const => {
1311+
if let Some(trait_def_id) = ast_trait_ref.trait_def_id() && !tcx.has_attr(trait_def_id, sym::const_trait) {
1312+
let trait_name = tcx.item_name(trait_def_id).to_string();
1313+
tcx.sess.emit_err(errors::ConstImplForNonConstTrait {
1314+
trait_ref_span: ast_trait_ref.path.span,
1315+
trait_name,
1316+
local_trait_span: trait_def_id.as_local().map(|_| tcx.def_span(trait_def_id).shrink_to_lo()),
1317+
marking: (),
1318+
adding: (),
1319+
});
1320+
ty::BoundConstness::NotConst
1321+
} else {
1322+
ty::BoundConstness::ConstIfConst
1323+
}
1324+
},
1325+
hir::Constness::NotConst => ty::BoundConstness::NotConst,
1326+
}
1327+
}
1328+
13251329
fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity {
13261330
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
13271331
let item = tcx.hir().expect_item(def_id.expect_local());

compiler/rustc_hir_analysis/src/errors.rs

+21
Original file line numberDiff line numberDiff line change
@@ -249,3 +249,24 @@ pub struct ExpectedUsedSymbol {
249249
#[primary_span]
250250
pub span: Span,
251251
}
252+
253+
#[derive(Diagnostic)]
254+
#[diag(hir_analysis_const_impl_for_non_const_trait)]
255+
pub struct ConstImplForNonConstTrait {
256+
#[primary_span]
257+
pub trait_ref_span: Span,
258+
pub trait_name: String,
259+
#[suggestion(applicability = "machine-applicable", code = "#[const_trait]")]
260+
pub local_trait_span: Option<Span>,
261+
#[note]
262+
pub marking: (),
263+
#[note(adding)]
264+
pub adding: (),
265+
}
266+
267+
#[derive(Diagnostic)]
268+
#[diag(hir_analysis_const_bound_for_non_const_trait)]
269+
pub struct ConstBoundForNonConstTrait {
270+
#[primary_span]
271+
pub span: Span,
272+
}

0 commit comments

Comments
 (0)