More informative error message for E0015

This commit is contained in:
Deadbeef 2021-11-03 17:34:30 +08:00
parent 9cdefd763b
commit 1b0dcdc341
No known key found for this signature in database
GPG Key ID: 6D017A96D8E6C2F9
2 changed files with 49 additions and 47 deletions

View File

@ -797,7 +797,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
if let Some(trait_id) = tcx.trait_of_item(callee) {
trace!("attempting to call a trait method");
if !self.tcx.features().const_trait_impl {
self.check_op(ops::FnCallNonConst(Some((callee, substs))));
self.check_op(ops::FnCallNonConst(callee, substs));
return;
}
@ -856,7 +856,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
if !nonconst_call_permission {
self.check_op(ops::FnCallNonConst(None));
self.check_op(ops::FnCallNonConst(callee, substs));
return;
}
}
@ -925,7 +925,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
}
if !nonconst_call_permission {
self.check_op(ops::FnCallNonConst(None));
self.check_op(ops::FnCallNonConst(callee, substs));
return;
}
}

View File

@ -74,19 +74,24 @@ impl NonConstOp for FnCallIndirect {
/// A function call where the callee is not marked as `const`.
#[derive(Debug)]
pub struct FnCallNonConst<'tcx>(pub Option<(DefId, SubstsRef<'tcx>)>);
pub struct FnCallNonConst<'tcx>(pub DefId, pub SubstsRef<'tcx>);
impl<'a> NonConstOp for FnCallNonConst<'a> {
fn build_error<'tcx>(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
let FnCallNonConst(def_id, substs) = *self;
let mut err = struct_span_err!(
ccx.tcx.sess,
span,
E0015,
"cannot call non-const fn `{}` in {}s",
ccx.tcx.def_path_str_with_substs(def_id, substs),
ccx.const_kind()
);
err.note(&format!(
"calls in {}s are limited to constant functions, \
tuple structs and tuple variants",
ccx.const_kind(),
);
));
if let FnCallNonConst(Some((callee, substs))) = *self {
if let Some(trait_def_id) = ccx.tcx.lang_items().eq_trait() {
if let Some(eq_item) = ccx.tcx.associated_items(trait_def_id).find_by_name_and_kind(
ccx.tcx,
@ -109,15 +114,13 @@ impl<'a> NonConstOp for FnCallNonConst<'a> {
}
let deref = "*".repeat(num_refs);
if let Ok(call_str) =
ccx.tcx.sess.source_map().span_to_snippet(span)
{
if let Ok(call_str) = ccx.tcx.sess.source_map().span_to_snippet(span) {
if let Some(eq_idx) = call_str.find("==") {
if let Some(rhs_idx) = call_str[(eq_idx + 2)..]
.find(|c: char| !c.is_whitespace())
if let Some(rhs_idx) =
call_str[(eq_idx + 2)..].find(|c: char| !c.is_whitespace())
{
let rhs_pos = span.lo()
+ BytePos::from_usize(eq_idx + 2 + rhs_idx);
let rhs_pos =
span.lo() + BytePos::from_usize(eq_idx + 2 + rhs_idx);
let rhs_span = span.with_lo(rhs_pos).with_hi(rhs_pos);
err.multipart_suggestion(
"consider dereferencing here",
@ -136,7 +139,6 @@ impl<'a> NonConstOp for FnCallNonConst<'a> {
}
}
}
}
err
}