Skip to content

Commit

Permalink
Split diagnostic details out into a separate function and fluent files
Browse files Browse the repository at this point in the history
  • Loading branch information
oli-obk committed Oct 25, 2022
1 parent 8286ea5 commit 1c26a27
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc_error_messages/locales/en-US/hir_analysis.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -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_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
5 changes: 1 addition & 4 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -539,10 +539,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
if let Some(ty::BoundConstness::ConstIfConst) = constness
&& generics.has_self && !tcx.has_attr(def_id, sym::const_trait)
{
tcx.sess.span_err(
span,
"~const can only be applied to `#[const_trait]` traits",
);
tcx.sess.emit_err(crate::errors::ConstBoundForNonConstTrait { span } );
}

(substs, arg_count)
Expand Down
48 changes: 26 additions & 22 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1294,34 +1294,38 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option<ty::TraitRef<'_>> {
&icx,
ast_trait_ref,
selfty,
match impl_.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);
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,
},
check_impl_constness(tcx, impl_.constness, ast_trait_ref),
)
}),
_ => 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 {
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
let item = tcx.hir().expect_item(def_id.expect_local());
Expand Down
21 changes: 21 additions & 0 deletions compiler/rustc_hir_analysis/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,24 @@ pub struct ExpectedUsedSymbol {
#[primary_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,
}

0 comments on commit 1c26a27

Please sign in to comment.