diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2021-11-03 17:34:30 +0800 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2022-02-12 19:24:04 +1100 |
| commit | 1b0dcdc341ea3659fd8d91ff85605069098ca34b (patch) | |
| tree | b121ab43d624b3d4ddf1eaa286b120186edf7079 /compiler/rustc_const_eval/src/transform | |
| parent | 9cdefd763b910ffd1d42233a8c752ab5fd84ca4d (diff) | |
| download | rust-1b0dcdc341ea3659fd8d91ff85605069098ca34b.tar.gz rust-1b0dcdc341ea3659fd8d91ff85605069098ca34b.zip | |
More informative error message for E0015
Diffstat (limited to 'compiler/rustc_const_eval/src/transform')
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/check.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/ops.rs | 94 |
2 files changed, 51 insertions, 49 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs index 12a8b8c6d77..ec96064222b 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs @@ -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; } } diff --git a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs index 24c4a4915e5..a6da3ebba6e 100644 --- a/compiler/rustc_const_eval/src/transform/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/transform/check_consts/ops.rs @@ -74,65 +74,67 @@ 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, - Ident::with_dummy_span(sym::eq), - AssocKind::Fn, - trait_def_id, - ) { - if callee == eq_item.def_id && substs.len() == 2 { - match (substs[0].unpack(), substs[1].unpack()) { - (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) - if self_ty == rhs_ty - && self_ty.is_ref() - && self_ty.peel_refs().is_primitive() => - { - let mut num_refs = 0; - let mut tmp_ty = self_ty; - while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() { - num_refs += 1; - tmp_ty = inner_ty; - } - let deref = "*".repeat(num_refs); - - 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()) - { - 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", - vec![ - (span.shrink_to_lo(), deref.clone()), - (rhs_span, deref), - ], - Applicability::MachineApplicable, - ); - } + )); + + 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, + Ident::with_dummy_span(sym::eq), + AssocKind::Fn, + trait_def_id, + ) { + if callee == eq_item.def_id && substs.len() == 2 { + match (substs[0].unpack(), substs[1].unpack()) { + (GenericArgKind::Type(self_ty), GenericArgKind::Type(rhs_ty)) + if self_ty == rhs_ty + && self_ty.is_ref() + && self_ty.peel_refs().is_primitive() => + { + let mut num_refs = 0; + let mut tmp_ty = self_ty; + while let rustc_middle::ty::Ref(_, inner_ty, _) = tmp_ty.kind() { + num_refs += 1; + tmp_ty = inner_ty; + } + let deref = "*".repeat(num_refs); + + 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()) + { + 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", + vec![ + (span.shrink_to_lo(), deref.clone()), + (rhs_span, deref), + ], + Applicability::MachineApplicable, + ); } } } - _ => {} } + _ => {} } } } |
