Unify conditional and non const call error reporting
This commit is contained in:
parent
5a9f0be0bd
commit
924000d70e
12 changed files with 300 additions and 261 deletions
|
@ -21,8 +21,6 @@ const_eval_closure_call =
|
|||
closures need an RFC before allowed to be called in {const_eval_const_context}s
|
||||
const_eval_closure_fndef_not_const =
|
||||
function defined here, but it is not `const`
|
||||
const_eval_conditionally_const_call =
|
||||
cannot call conditionally-const {$def_descr} `{$def_path_str}` in {const_eval_const_context}s
|
||||
|
||||
const_eval_consider_dereferencing =
|
||||
consider dereferencing here
|
||||
|
@ -239,18 +237,18 @@ const_eval_non_const_await =
|
|||
cannot convert `{$ty}` into a future in {const_eval_const_context}s
|
||||
|
||||
const_eval_non_const_closure =
|
||||
cannot call {$non}-const closure in {const_eval_const_context}s
|
||||
cannot call {$non_or_conditionally}-const closure in {const_eval_const_context}s
|
||||
|
||||
const_eval_non_const_deref_coercion =
|
||||
cannot perform {$non}-const deref coercion on `{$ty}` in {const_eval_const_context}s
|
||||
cannot perform {$non_or_conditionally}-const deref coercion on `{$ty}` in {const_eval_const_context}s
|
||||
.note = attempting to deref into `{$target_ty}`
|
||||
.target_note = deref defined here
|
||||
|
||||
const_eval_non_const_fmt_macro_call =
|
||||
cannot call {$non}-const formatting macro in {const_eval_const_context}s
|
||||
cannot call {$non_or_conditionally}-const formatting macro in {const_eval_const_context}s
|
||||
|
||||
const_eval_non_const_fn_call =
|
||||
cannot call {$non}-const {$def_descr} `{$def_path_str}` in {const_eval_const_context}s
|
||||
cannot call {$non_or_conditionally}-const {$def_descr} `{$def_path_str}` in {const_eval_const_context}s
|
||||
|
||||
const_eval_non_const_for_loop_into_iter =
|
||||
cannot use `for` loop on `{$ty}` in {const_eval_const_context}s
|
||||
|
@ -259,13 +257,13 @@ const_eval_non_const_impl =
|
|||
impl defined here, but it is not `const`
|
||||
|
||||
const_eval_non_const_intrinsic =
|
||||
cannot call {$non}-const intrinsic `{$name}` in {const_eval_const_context}s
|
||||
cannot call non-const intrinsic `{$name}` in {const_eval_const_context}s
|
||||
|
||||
const_eval_non_const_match_eq = cannot match on `{$ty}` in {const_eval_const_context}s
|
||||
.note = `{$ty}` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||
|
||||
const_eval_non_const_operator =
|
||||
cannot call {$non}-const operator in {const_eval_const_context}s
|
||||
cannot call {$non_or_conditionally}-const operator in {const_eval_const_context}s
|
||||
|
||||
const_eval_non_const_question_branch =
|
||||
`?` is not allowed on `{$ty}` in {const_eval_const_context}s
|
||||
|
|
|
@ -708,7 +708,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
|
||||
if trait_is_const {
|
||||
// Trait calls are always conditionally-const.
|
||||
self.check_op(ops::ConditionallyConstCall { callee, args: fn_args });
|
||||
self.check_op(ops::ConditionallyConstCall {
|
||||
callee,
|
||||
args: fn_args,
|
||||
span: *fn_span,
|
||||
call_source,
|
||||
});
|
||||
// FIXME(const_trait_impl): do a more fine-grained check whether this
|
||||
// particular trait can be const-stably called.
|
||||
} else {
|
||||
|
@ -726,7 +731,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||
|
||||
// Even if we know the callee, ensure we can use conditionally-const calls.
|
||||
if has_const_conditions {
|
||||
self.check_op(ops::ConditionallyConstCall { callee, args: fn_args });
|
||||
self.check_op(ops::ConditionallyConstCall {
|
||||
callee,
|
||||
args: fn_args,
|
||||
span: *fn_span,
|
||||
call_source,
|
||||
});
|
||||
}
|
||||
|
||||
// At this point, we are calling a function, `callee`, whose `DefId` is known...
|
||||
|
|
|
@ -15,6 +15,7 @@ use rustc_middle::ty::{
|
|||
suggest_constraining_type_param,
|
||||
};
|
||||
use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind};
|
||||
use rustc_session::parse::add_feature_diagnostics;
|
||||
use rustc_span::{BytePos, Pos, Span, Symbol, sym};
|
||||
use rustc_trait_selection::traits::SelectionContext;
|
||||
use tracing::debug;
|
||||
|
@ -77,6 +78,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
|
|||
pub(crate) struct ConditionallyConstCall<'tcx> {
|
||||
pub callee: DefId,
|
||||
pub args: GenericArgsRef<'tcx>,
|
||||
pub span: Span,
|
||||
pub call_source: CallSource,
|
||||
}
|
||||
|
||||
impl<'tcx> NonConstOp<'tcx> for ConditionallyConstCall<'tcx> {
|
||||
|
@ -91,24 +94,22 @@ impl<'tcx> NonConstOp<'tcx> for ConditionallyConstCall<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> Diag<'tcx> {
|
||||
let mut err = ccx.tcx.sess.create_feature_err(
|
||||
errors::ConditionallyConstCall {
|
||||
span,
|
||||
def_path_str: ccx.tcx.def_path_str_with_args(self.callee, self.args),
|
||||
def_descr: ccx.tcx.def_descr(self.callee),
|
||||
kind: ccx.const_kind(),
|
||||
},
|
||||
sym::const_trait_impl,
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
|
||||
let mut diag = build_error_for_const_call(
|
||||
ccx,
|
||||
self.callee,
|
||||
self.args,
|
||||
self.span,
|
||||
self.call_source,
|
||||
"conditionally",
|
||||
|_, _, _| {},
|
||||
);
|
||||
|
||||
err.note(format!(
|
||||
"calls in {}s are limited to constant functions, \
|
||||
tuple structs and tuple variants",
|
||||
ccx.const_kind(),
|
||||
));
|
||||
// Override code and mention feature.
|
||||
diag.code(E0658);
|
||||
add_feature_diagnostics(&mut diag, ccx.tcx.sess, sym::const_trait_impl);
|
||||
|
||||
err
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,209 +127,59 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
|||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
|
||||
let FnCallNonConst { callee, args, span, call_source } = *self;
|
||||
let ConstCx { tcx, typing_env, .. } = *ccx;
|
||||
let tcx = ccx.tcx;
|
||||
let caller = ccx.def_id();
|
||||
|
||||
let note_trait_if_possible = |err, self_ty: Ty<'_>, trait_id| {
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, args);
|
||||
let mut err = build_error_for_const_call(
|
||||
ccx,
|
||||
self.callee,
|
||||
self.args,
|
||||
self.span,
|
||||
self.call_source,
|
||||
"non",
|
||||
|err, self_ty, trait_id| {
|
||||
// FIXME(const_trait_impl): Do we need any of this on the non-const codepath?
|
||||
|
||||
match self_ty.kind() {
|
||||
Param(param_ty) => {
|
||||
debug!(?param_ty);
|
||||
if let Some(generics) = tcx.hir_node_by_def_id(caller).generics() {
|
||||
let constraint = with_no_trimmed_paths!(format!(
|
||||
"~const {}",
|
||||
trait_ref.print_trait_sugared(),
|
||||
));
|
||||
suggest_constraining_type_param(
|
||||
tcx,
|
||||
generics,
|
||||
err,
|
||||
param_ty.name.as_str(),
|
||||
&constraint,
|
||||
Some(trait_ref.def_id),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
ty::Adt(..) => {
|
||||
let (infcx, param_env) = tcx.infer_ctxt().build_with_typing_env(typing_env);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
let implsrc = selcx.select(&obligation);
|
||||
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
|
||||
// FIXME(const_trait_impl) revisit this
|
||||
if !tcx.is_const_trait_impl(data.impl_def_id) {
|
||||
let span = tcx.def_span(data.impl_def_id);
|
||||
err.subdiagnostic(errors::NonConstImplNote { span });
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, self.args);
|
||||
|
||||
match self_ty.kind() {
|
||||
Param(param_ty) => {
|
||||
debug!(?param_ty);
|
||||
if let Some(generics) = tcx.hir_node_by_def_id(caller).generics() {
|
||||
let constraint = with_no_trimmed_paths!(format!(
|
||||
"~const {}",
|
||||
trait_ref.print_trait_sugared(),
|
||||
));
|
||||
suggest_constraining_type_param(
|
||||
tcx,
|
||||
generics,
|
||||
err,
|
||||
param_ty.name.as_str(),
|
||||
&constraint,
|
||||
Some(trait_ref.def_id),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
};
|
||||
|
||||
let call_kind =
|
||||
call_kind(tcx, ccx.typing_env, callee, args, span, call_source.from_hir_call(), None);
|
||||
|
||||
debug!(?call_kind);
|
||||
|
||||
let mut err = match call_kind {
|
||||
CallKind::Normal { desugaring: Some((kind, self_ty)), .. } => {
|
||||
macro_rules! error {
|
||||
($err:ident) => {
|
||||
tcx.dcx().create_err(errors::$err {
|
||||
span,
|
||||
ty: self_ty,
|
||||
kind: ccx.const_kind(),
|
||||
non: "non",
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
// Don't point at the trait if this is a desugaring...
|
||||
// FIXME(const_trait_impl): we could perhaps do this for `Iterator`.
|
||||
match kind {
|
||||
CallDesugaringKind::ForLoopIntoIter | CallDesugaringKind::ForLoopNext => {
|
||||
error!(NonConstForLoopIntoIter)
|
||||
}
|
||||
CallDesugaringKind::QuestionBranch => {
|
||||
error!(NonConstQuestionBranch)
|
||||
}
|
||||
CallDesugaringKind::QuestionFromResidual => {
|
||||
error!(NonConstQuestionFromResidual)
|
||||
}
|
||||
CallDesugaringKind::TryBlockFromOutput => {
|
||||
error!(NonConstTryBlockFromOutput)
|
||||
}
|
||||
CallDesugaringKind::Await => {
|
||||
error!(NonConstAwait)
|
||||
}
|
||||
}
|
||||
}
|
||||
CallKind::FnCall { fn_trait_id, self_ty } => {
|
||||
let note = match self_ty.kind() {
|
||||
FnDef(def_id, ..) => {
|
||||
let span = tcx.def_span(*def_id);
|
||||
if ccx.tcx.is_const_fn(*def_id) {
|
||||
span_bug!(span, "calling const FnDef errored when it shouldn't");
|
||||
}
|
||||
|
||||
Some(errors::NonConstClosureNote::FnDef { span })
|
||||
}
|
||||
FnPtr(..) => Some(errors::NonConstClosureNote::FnPtr),
|
||||
Closure(..) => Some(errors::NonConstClosureNote::Closure),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let mut err = tcx.dcx().create_err(errors::NonConstClosure {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
note,
|
||||
non: "non",
|
||||
});
|
||||
|
||||
note_trait_if_possible(&mut err, self_ty, fn_trait_id);
|
||||
err
|
||||
}
|
||||
CallKind::Operator { trait_id, self_ty, .. } => {
|
||||
let mut err = if let CallSource::MatchCmp = call_source {
|
||||
tcx.dcx().create_err(errors::NonConstMatchEq {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
ty: self_ty,
|
||||
non: "non",
|
||||
})
|
||||
} else {
|
||||
let mut sugg = None;
|
||||
|
||||
if ccx.tcx.is_lang_item(trait_id, LangItem::PartialEq) {
|
||||
match (args[0].unpack(), args[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);
|
||||
sugg = Some(errors::ConsiderDereferencing {
|
||||
deref,
|
||||
span: span.shrink_to_lo(),
|
||||
rhs_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
ty::Adt(..) => {
|
||||
let (infcx, param_env) =
|
||||
tcx.infer_ctxt().build_with_typing_env(ccx.typing_env);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
let mut selcx = SelectionContext::new(&infcx);
|
||||
let implsrc = selcx.select(&obligation);
|
||||
if let Ok(Some(ImplSource::UserDefined(data))) = implsrc {
|
||||
// FIXME(const_trait_impl) revisit this
|
||||
if !tcx.is_const_trait_impl(data.impl_def_id) {
|
||||
let span = tcx.def_span(data.impl_def_id);
|
||||
err.subdiagnostic(errors::NonConstImplNote { span });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
tcx.dcx().create_err(errors::NonConstOperator {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
sugg,
|
||||
non: "non",
|
||||
})
|
||||
};
|
||||
|
||||
note_trait_if_possible(&mut err, self_ty, trait_id);
|
||||
err
|
||||
}
|
||||
CallKind::DerefCoercion { deref_target, deref_target_ty, self_ty } => {
|
||||
// Check first whether the source is accessible (issue #87060)
|
||||
let target = if tcx.sess.source_map().is_span_accessible(deref_target) {
|
||||
Some(deref_target)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut err = tcx.dcx().create_err(errors::NonConstDerefCoercion {
|
||||
span,
|
||||
ty: self_ty,
|
||||
kind: ccx.const_kind(),
|
||||
target_ty: deref_target_ty,
|
||||
deref_target: target,
|
||||
non: "non",
|
||||
});
|
||||
|
||||
note_trait_if_possible(&mut err, self_ty, tcx.require_lang_item(LangItem::Deref, Some(span)));
|
||||
err
|
||||
}
|
||||
_ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentMethods) => {
|
||||
ccx.dcx().create_err(errors::NonConstFmtMacroCall { span, kind: ccx.const_kind(), non: "non" })
|
||||
}
|
||||
_ => ccx.dcx().create_err(errors::NonConstFnCall {
|
||||
span,
|
||||
def_descr: ccx.tcx.def_descr(callee),
|
||||
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
|
||||
kind: ccx.const_kind(),
|
||||
non: "non",
|
||||
}),
|
||||
};
|
||||
|
||||
err.note(format!(
|
||||
"calls in {}s are limited to constant functions, \
|
||||
tuple structs and tuple variants",
|
||||
ccx.const_kind(),
|
||||
));
|
||||
_ => {}
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
if let ConstContext::Static(_) = ccx.const_kind() {
|
||||
err.note(fluent_generated::const_eval_lazy_lock);
|
||||
|
@ -338,6 +189,190 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Build an error message reporting that a function call is not const (or only
|
||||
/// conditionally const). In case that this call is desugared (like an operator
|
||||
/// or sugar from something like a `for` loop), try to build a better error message
|
||||
/// that doesn't call it a method.
|
||||
fn build_error_for_const_call<'tcx>(
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
callee: DefId,
|
||||
args: ty::GenericArgsRef<'tcx>,
|
||||
span: Span,
|
||||
call_source: CallSource,
|
||||
non_or_conditionally: &'static str,
|
||||
note_trait_if_possible: impl FnOnce(&mut Diag<'tcx>, Ty<'tcx>, DefId),
|
||||
) -> Diag<'tcx> {
|
||||
let tcx = ccx.tcx;
|
||||
|
||||
let call_kind =
|
||||
call_kind(tcx, ccx.typing_env, callee, args, span, call_source.from_hir_call(), None);
|
||||
|
||||
debug!(?call_kind);
|
||||
|
||||
let mut err = match call_kind {
|
||||
CallKind::Normal { desugaring: Some((kind, self_ty)), .. } => {
|
||||
macro_rules! error {
|
||||
($err:ident) => {
|
||||
tcx.dcx().create_err(errors::$err {
|
||||
span,
|
||||
ty: self_ty,
|
||||
kind: ccx.const_kind(),
|
||||
non_or_conditionally,
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
// Don't point at the trait if this is a desugaring...
|
||||
// FIXME(const_trait_impl): we could perhaps do this for `Iterator`.
|
||||
match kind {
|
||||
CallDesugaringKind::ForLoopIntoIter | CallDesugaringKind::ForLoopNext => {
|
||||
error!(NonConstForLoopIntoIter)
|
||||
}
|
||||
CallDesugaringKind::QuestionBranch => {
|
||||
error!(NonConstQuestionBranch)
|
||||
}
|
||||
CallDesugaringKind::QuestionFromResidual => {
|
||||
error!(NonConstQuestionFromResidual)
|
||||
}
|
||||
CallDesugaringKind::TryBlockFromOutput => {
|
||||
error!(NonConstTryBlockFromOutput)
|
||||
}
|
||||
CallDesugaringKind::Await => {
|
||||
error!(NonConstAwait)
|
||||
}
|
||||
}
|
||||
}
|
||||
CallKind::FnCall { fn_trait_id, self_ty } => {
|
||||
let note = match self_ty.kind() {
|
||||
FnDef(def_id, ..) => {
|
||||
let span = tcx.def_span(*def_id);
|
||||
if ccx.tcx.is_const_fn(*def_id) {
|
||||
span_bug!(span, "calling const FnDef errored when it shouldn't");
|
||||
}
|
||||
|
||||
Some(errors::NonConstClosureNote::FnDef { span })
|
||||
}
|
||||
FnPtr(..) => Some(errors::NonConstClosureNote::FnPtr),
|
||||
Closure(..) => Some(errors::NonConstClosureNote::Closure),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let mut err = tcx.dcx().create_err(errors::NonConstClosure {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
note,
|
||||
non_or_conditionally,
|
||||
});
|
||||
|
||||
note_trait_if_possible(&mut err, self_ty, fn_trait_id);
|
||||
err
|
||||
}
|
||||
CallKind::Operator { trait_id, self_ty, .. } => {
|
||||
let mut err = if let CallSource::MatchCmp = call_source {
|
||||
tcx.dcx().create_err(errors::NonConstMatchEq {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
ty: self_ty,
|
||||
non_or_conditionally,
|
||||
})
|
||||
} else {
|
||||
let mut sugg = None;
|
||||
|
||||
if ccx.tcx.is_lang_item(trait_id, LangItem::PartialEq) {
|
||||
match (args[0].unpack(), args[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);
|
||||
sugg = Some(errors::ConsiderDereferencing {
|
||||
deref,
|
||||
span: span.shrink_to_lo(),
|
||||
rhs_span,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
tcx.dcx().create_err(errors::NonConstOperator {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
sugg,
|
||||
non_or_conditionally,
|
||||
})
|
||||
};
|
||||
|
||||
note_trait_if_possible(&mut err, self_ty, trait_id);
|
||||
err
|
||||
}
|
||||
CallKind::DerefCoercion { deref_target, deref_target_ty, self_ty } => {
|
||||
// Check first whether the source is accessible (issue #87060)
|
||||
let target = if tcx.sess.source_map().is_span_accessible(deref_target) {
|
||||
Some(deref_target)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let mut err = tcx.dcx().create_err(errors::NonConstDerefCoercion {
|
||||
span,
|
||||
ty: self_ty,
|
||||
kind: ccx.const_kind(),
|
||||
target_ty: deref_target_ty,
|
||||
deref_target: target,
|
||||
non_or_conditionally,
|
||||
});
|
||||
|
||||
note_trait_if_possible(
|
||||
&mut err,
|
||||
self_ty,
|
||||
tcx.require_lang_item(LangItem::Deref, Some(span)),
|
||||
);
|
||||
err
|
||||
}
|
||||
_ if tcx.opt_parent(callee) == tcx.get_diagnostic_item(sym::ArgumentMethods) => {
|
||||
ccx.dcx().create_err(errors::NonConstFmtMacroCall {
|
||||
span,
|
||||
kind: ccx.const_kind(),
|
||||
non_or_conditionally,
|
||||
})
|
||||
}
|
||||
_ => ccx.dcx().create_err(errors::NonConstFnCall {
|
||||
span,
|
||||
def_descr: ccx.tcx.def_descr(callee),
|
||||
def_path_str: ccx.tcx.def_path_str_with_args(callee, args),
|
||||
kind: ccx.const_kind(),
|
||||
non_or_conditionally,
|
||||
}),
|
||||
};
|
||||
|
||||
err.note(format!(
|
||||
"calls in {}s are limited to constant functions, \
|
||||
tuple structs and tuple variants",
|
||||
ccx.const_kind(),
|
||||
));
|
||||
|
||||
err
|
||||
}
|
||||
|
||||
/// A call to an `#[unstable]` const fn or `#[rustc_const_unstable]` function.
|
||||
///
|
||||
/// Contains the name of the feature that would allow the use of this function.
|
||||
|
|
|
@ -174,17 +174,7 @@ pub(crate) struct NonConstFmtMacroCall {
|
|||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(const_eval_conditionally_const_call)]
|
||||
pub(crate) struct ConditionallyConstCall {
|
||||
#[primary_span]
|
||||
pub span: Span,
|
||||
pub def_path_str: String,
|
||||
pub def_descr: &'static str,
|
||||
pub kind: ConstContext,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -195,7 +185,7 @@ pub(crate) struct NonConstFnCall {
|
|||
pub def_path_str: String,
|
||||
pub def_descr: &'static str,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -302,7 +292,7 @@ pub struct NonConstMatchEq<'tcx> {
|
|||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -312,7 +302,7 @@ pub struct NonConstForLoopIntoIter<'tcx> {
|
|||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -322,7 +312,7 @@ pub struct NonConstQuestionBranch<'tcx> {
|
|||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -332,7 +322,7 @@ pub struct NonConstQuestionFromResidual<'tcx> {
|
|||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -342,7 +332,7 @@ pub struct NonConstTryBlockFromOutput<'tcx> {
|
|||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -352,7 +342,7 @@ pub struct NonConstAwait<'tcx> {
|
|||
pub span: Span,
|
||||
pub ty: Ty<'tcx>,
|
||||
pub kind: ConstContext,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -363,7 +353,7 @@ pub struct NonConstClosure {
|
|||
pub kind: ConstContext,
|
||||
#[subdiagnostic]
|
||||
pub note: Option<NonConstClosureNote>,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
|
@ -397,7 +387,7 @@ pub struct NonConstOperator {
|
|||
pub kind: ConstContext,
|
||||
#[subdiagnostic]
|
||||
pub sugg: Option<ConsiderDereferencing>,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -411,7 +401,7 @@ pub struct NonConstDerefCoercion<'tcx> {
|
|||
pub target_ty: Ty<'tcx>,
|
||||
#[note(const_eval_target_note)]
|
||||
pub deref_target: Option<Span>,
|
||||
pub non: &'static str,
|
||||
pub non_or_conditionally: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
@ -2,7 +2,7 @@ struct A;
|
|||
struct B;
|
||||
|
||||
static S: &'static B = &A;
|
||||
//~^ ERROR cannot call conditionally-const method
|
||||
//~^ ERROR cannot perform conditionally-const deref coercion
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
error[E0658]: cannot call conditionally-const method `<A as Deref>::deref` in statics
|
||||
error[E0658]: cannot perform conditionally-const deref coercion on `A` in statics
|
||||
--> $DIR/issue-25901.rs:4:24
|
||||
|
|
||||
LL | static S: &'static B = &A;
|
||||
| ^^
|
||||
|
|
||||
= note: attempting to deref into `B`
|
||||
note: deref defined here
|
||||
--> $DIR/issue-25901.rs:10:5
|
||||
|
|
||||
LL | type Target = B;
|
||||
| ^^^^^^^^^^^
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in statics are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ error[E0658]: cannot call conditionally-const method `<R as Deref>::deref` in co
|
|||
LL | self.0
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0493]: destructor of `R` cannot be evaluated at compile-time
|
||||
--> $DIR/arbitrary-self-from-method-substs-ice.rs:10:43
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
error[E0658]: cannot call conditionally-const method `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
|
||||
--> $DIR/cross-crate.rs:22:5
|
||||
--> $DIR/cross-crate.rs:22:11
|
||||
|
|
||||
LL | Const.func();
|
||||
| ^^^^^^^^^^^^
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
error[E0658]: cannot call conditionally-const method `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
|
||||
--> $DIR/cross-crate.rs:19:5
|
||||
--> $DIR/cross-crate.rs:19:14
|
||||
|
|
||||
LL | NonConst.func();
|
||||
| ^^^^^^^^^^^^^^^
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0658]: cannot call conditionally-const method `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
|
||||
--> $DIR/cross-crate.rs:22:5
|
||||
--> $DIR/cross-crate.rs:22:11
|
||||
|
|
||||
LL | Const.func();
|
||||
| ^^^^^^^^^^^^
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@ error[E0658]: cannot call conditionally-const associated function `<staged_api::
|
|||
LL | Unstable::func();
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
|
|
|
@ -39,15 +39,15 @@ LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)]
|
|||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: cannot call conditionally-const method `<T as Foo>::a` in constant functions
|
||||
--> $DIR/super-traits-fail-3.rs:36:5
|
||||
--> $DIR/super-traits-fail-3.rs:36:7
|
||||
|
|
||||
LL | x.a();
|
||||
| ^^^^^
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
|
@ -39,15 +39,15 @@ LL | #[cfg_attr(any(yyy, yny, nyy, nyn), const_trait)]
|
|||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: cannot call conditionally-const method `<T as Foo>::a` in constant functions
|
||||
--> $DIR/super-traits-fail-3.rs:36:5
|
||||
--> $DIR/super-traits-fail-3.rs:36:7
|
||||
|
|
||||
LL | x.a();
|
||||
| ^^^^^
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
= note: see issue #67792 <https://github.com/rust-lang/rust/issues/67792> for more information
|
||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue