Auto merge of #114134 - fee1-dead-contrib:rm-constness-from-param-env, r=oli-obk
Remove `constness` from `ParamEnv` This should be replaced by keyword generics/effects. cc #110395 r? `@oli-obk`
This commit is contained in:
commit
aafd75a9c5
102 changed files with 423 additions and 1061 deletions
|
@ -409,18 +409,12 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let ty::FnDef(def_id, args) = *constant.literal.ty().kind() {
|
if let ty::FnDef(def_id, args) = *constant.literal.ty().kind() {
|
||||||
// const_trait_impl: use a non-const param env when checking that a FnDef type is well formed.
|
|
||||||
// this is because the well-formedness of the function does not need to be proved to have `const`
|
|
||||||
// impls for trait bounds.
|
|
||||||
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
|
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, args);
|
||||||
let prev = self.cx.param_env;
|
|
||||||
self.cx.param_env = prev.without_const();
|
|
||||||
self.cx.normalize_and_prove_instantiated_predicates(
|
self.cx.normalize_and_prove_instantiated_predicates(
|
||||||
def_id,
|
def_id,
|
||||||
instantiated_predicates,
|
instantiated_predicates,
|
||||||
locations,
|
locations,
|
||||||
);
|
);
|
||||||
self.cx.param_env = prev;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,7 +228,6 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||||
) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
|
) -> ::rustc_middle::mir::interpret::EvalToConstValueResult<'tcx> {
|
||||||
assert!(key.param_env.is_const());
|
|
||||||
// see comment in eval_to_allocation_raw_provider for what we're doing here
|
// see comment in eval_to_allocation_raw_provider for what we're doing here
|
||||||
if key.param_env.reveal() == Reveal::All {
|
if key.param_env.reveal() == Reveal::All {
|
||||||
let mut key = key;
|
let mut key = key;
|
||||||
|
@ -269,7 +268,6 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||||
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
|
) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
|
||||||
assert!(key.param_env.is_const());
|
|
||||||
// Because the constant is computed twice (once per value of `Reveal`), we are at risk of
|
// Because the constant is computed twice (once per value of `Reveal`), we are at risk of
|
||||||
// reporting the same error twice here. To resolve this, we check whether we can evaluate the
|
// reporting the same error twice here. To resolve this, we check whether we can evaluate the
|
||||||
// constant in the more restrictive `Reveal::UserFacing`, which most likely already was
|
// constant in the more restrictive `Reveal::UserFacing`, which most likely already was
|
||||||
|
|
|
@ -28,15 +28,18 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
|
||||||
&& tcx.constness(parent_id) == hir::Constness::Const
|
&& tcx.constness(parent_id) == hir::Constness::Const
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks whether an item is considered to be `const`. If it is a constructor, it is const. If
|
/// Checks whether an item is considered to be `const`. If it is a constructor, anonymous const,
|
||||||
/// it is a trait impl/function, return if it has a `const` modifier. If it is an intrinsic,
|
/// const block, const item or associated const, it is const. If it is a trait impl/function,
|
||||||
/// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return
|
/// return if it has a `const` modifier. If it is an intrinsic, report whether said intrinsic
|
||||||
/// `Constness::NotConst`.
|
/// has a `rustc_const_{un,}stable` attribute. Otherwise, return `Constness::NotConst`.
|
||||||
fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
|
fn constness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::Constness {
|
||||||
let node = tcx.hir().get_by_def_id(def_id);
|
let node = tcx.hir().get_by_def_id(def_id);
|
||||||
|
|
||||||
match node {
|
match node {
|
||||||
hir::Node::Ctor(_) => hir::Constness::Const,
|
hir::Node::Ctor(_)
|
||||||
|
| hir::Node::AnonConst(_)
|
||||||
|
| hir::Node::ConstBlock(_)
|
||||||
|
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) => hir::Constness::Const,
|
||||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
|
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness,
|
||||||
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
|
hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => {
|
||||||
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
|
// Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other
|
||||||
|
|
|
@ -958,7 +958,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
} else {
|
} else {
|
||||||
self.param_env
|
self.param_env
|
||||||
};
|
};
|
||||||
let param_env = param_env.with_const();
|
|
||||||
let val = self.ctfe_query(span, |tcx| tcx.eval_to_allocation_raw(param_env.and(gid)))?;
|
let val = self.ctfe_query(span, |tcx| tcx.eval_to_allocation_raw(param_env.and(gid)))?;
|
||||||
self.raw_const_to_mplace(val)
|
self.raw_const_to_mplace(val)
|
||||||
}
|
}
|
||||||
|
|
|
@ -698,10 +698,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
ty::ConstKind::Unevaluated(uv) => {
|
ty::ConstKind::Unevaluated(uv) => {
|
||||||
let instance = self.resolve(uv.def, uv.args)?;
|
let instance = self.resolve(uv.def, uv.args)?;
|
||||||
let cid = GlobalId { instance, promoted: None };
|
let cid = GlobalId { instance, promoted: None };
|
||||||
self.ctfe_query(span, |tcx| {
|
self.ctfe_query(span, |tcx| tcx.eval_to_valtree(self.param_env.and(cid)))?
|
||||||
tcx.eval_to_valtree(self.param_env.with_const().and(cid))
|
.unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}"))
|
||||||
})?
|
|
||||||
.unwrap_or_else(|| bug!("unable to create ValTree for {uv:?}"))
|
|
||||||
}
|
}
|
||||||
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
|
ty::ConstKind::Bound(..) | ty::ConstKind::Infer(..) => {
|
||||||
span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {val:?}")
|
span_bug!(self.cur_span(), "unexpected ConstKind in ctfe: {val:?}")
|
||||||
|
|
|
@ -21,7 +21,7 @@ use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use super::ops::{self, NonConstOp, Status};
|
use super::ops::{self, NonConstOp, Status};
|
||||||
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop, NeedsNonConstDrop};
|
use super::qualifs::{self, CustomEq, HasMutInterior, NeedsDrop};
|
||||||
use super::resolver::FlowSensitiveAnalysis;
|
use super::resolver::FlowSensitiveAnalysis;
|
||||||
use super::{ConstCx, Qualif};
|
use super::{ConstCx, Qualif};
|
||||||
use crate::const_eval::is_unstable_const_fn;
|
use crate::const_eval::is_unstable_const_fn;
|
||||||
|
@ -34,7 +34,7 @@ type QualifResults<'mir, 'tcx, Q> =
|
||||||
pub struct Qualifs<'mir, 'tcx> {
|
pub struct Qualifs<'mir, 'tcx> {
|
||||||
has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
|
has_mut_interior: Option<QualifResults<'mir, 'tcx, HasMutInterior>>,
|
||||||
needs_drop: Option<QualifResults<'mir, 'tcx, NeedsDrop>>,
|
needs_drop: Option<QualifResults<'mir, 'tcx, NeedsDrop>>,
|
||||||
needs_non_const_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
|
// needs_non_const_drop: Option<QualifResults<'mir, 'tcx, NeedsNonConstDrop>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
|
impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
|
||||||
|
@ -77,15 +77,17 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
|
||||||
local: Local,
|
local: Local,
|
||||||
location: Location,
|
location: Location,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
// FIXME(effects) replace with `NeedsNonconstDrop` after const traits work again
|
||||||
|
/*
|
||||||
let ty = ccx.body.local_decls[local].ty;
|
let ty = ccx.body.local_decls[local].ty;
|
||||||
if !NeedsNonConstDrop::in_any_value_of_ty(ccx, ty) {
|
if !NeedsDrop::in_any_value_of_ty(ccx, ty) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let needs_non_const_drop = self.needs_non_const_drop.get_or_insert_with(|| {
|
let needs_non_const_drop = self.needs_non_const_drop.get_or_insert_with(|| {
|
||||||
let ConstCx { tcx, body, .. } = *ccx;
|
let ConstCx { tcx, body, .. } = *ccx;
|
||||||
|
|
||||||
FlowSensitiveAnalysis::new(NeedsNonConstDrop, ccx)
|
FlowSensitiveAnalysis::new(NeedsDrop, ccx)
|
||||||
.into_engine(tcx, &body)
|
.into_engine(tcx, &body)
|
||||||
.iterate_to_fixpoint()
|
.iterate_to_fixpoint()
|
||||||
.into_results_cursor(&body)
|
.into_results_cursor(&body)
|
||||||
|
@ -93,6 +95,9 @@ impl<'mir, 'tcx> Qualifs<'mir, 'tcx> {
|
||||||
|
|
||||||
needs_non_const_drop.seek_before_primary_effect(location);
|
needs_non_const_drop.seek_before_primary_effect(location);
|
||||||
needs_non_const_drop.get().contains(local)
|
needs_non_const_drop.get().contains(local)
|
||||||
|
*/
|
||||||
|
|
||||||
|
self.needs_drop(ccx, local, location)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
|
/// Returns `true` if `local` is `HasMutInterior` at the given `Location`.
|
||||||
|
@ -798,16 +803,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
}
|
}
|
||||||
Ok(Some(ImplSource::UserDefined(data))) => {
|
Ok(Some(ImplSource::UserDefined(data))) => {
|
||||||
let callee_name = tcx.item_name(callee);
|
let callee_name = tcx.item_name(callee);
|
||||||
if let Some(&did) = tcx
|
|
||||||
.associated_item_def_ids(data.impl_def_id)
|
|
||||||
.iter()
|
|
||||||
.find(|did| tcx.item_name(**did) == callee_name)
|
|
||||||
{
|
|
||||||
// using internal args is ok here, since this is only
|
|
||||||
// used for the `resolve` call below
|
|
||||||
fn_args = GenericArgs::identity_for_item(tcx, did);
|
|
||||||
callee = did;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let hir::Constness::NotConst = tcx.constness(data.impl_def_id) {
|
if let hir::Constness::NotConst = tcx.constness(data.impl_def_id) {
|
||||||
self.check_op(ops::FnCallNonConst {
|
self.check_op(ops::FnCallNonConst {
|
||||||
|
@ -820,6 +815,17 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(&did) = tcx
|
||||||
|
.associated_item_def_ids(data.impl_def_id)
|
||||||
|
.iter()
|
||||||
|
.find(|did| tcx.item_name(**did) == callee_name)
|
||||||
|
{
|
||||||
|
// using internal args is ok here, since this is only
|
||||||
|
// used for the `resolve` call below
|
||||||
|
fn_args = GenericArgs::identity_for_item(tcx, did);
|
||||||
|
callee = did;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ if !tcx.is_const_fn_raw(callee) => {
|
_ if !tcx.is_const_fn_raw(callee) => {
|
||||||
// At this point, it is only legal when the caller is in a trait
|
// At this point, it is only legal when the caller is in a trait
|
||||||
|
@ -996,8 +1002,9 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||||
let mut err_span = self.span;
|
let mut err_span = self.span;
|
||||||
let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty;
|
let ty_of_dropped_place = dropped_place.ty(self.body, self.tcx).ty;
|
||||||
|
|
||||||
|
// FIXME(effects) replace with `NeedsNonConstDrop` once we fix const traits
|
||||||
let ty_needs_non_const_drop =
|
let ty_needs_non_const_drop =
|
||||||
qualifs::NeedsNonConstDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place);
|
qualifs::NeedsDrop::in_any_value_of_ty(self.ccx, ty_of_dropped_place);
|
||||||
|
|
||||||
debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop);
|
debug!(?ty_of_dropped_place, ?ty_needs_non_const_drop);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ use rustc_span::{symbol::sym, Span};
|
||||||
|
|
||||||
use super::check::Qualifs;
|
use super::check::Qualifs;
|
||||||
use super::ops::{self, NonConstOp};
|
use super::ops::{self, NonConstOp};
|
||||||
use super::qualifs::{NeedsNonConstDrop, Qualif};
|
use super::qualifs::{NeedsDrop, Qualif};
|
||||||
use super::ConstCx;
|
use super::ConstCx;
|
||||||
|
|
||||||
/// Returns `true` if we should use the more precise live drop checker that runs after drop
|
/// Returns `true` if we should use the more precise live drop checker that runs after drop
|
||||||
|
@ -82,7 +82,9 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
|
||||||
match &terminator.kind {
|
match &terminator.kind {
|
||||||
mir::TerminatorKind::Drop { place: dropped_place, .. } => {
|
mir::TerminatorKind::Drop { place: dropped_place, .. } => {
|
||||||
let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
|
let dropped_ty = dropped_place.ty(self.body, self.tcx).ty;
|
||||||
if !NeedsNonConstDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
|
|
||||||
|
// FIXME(effects) use `NeedsNonConstDrop`
|
||||||
|
if !NeedsDrop::in_any_value_of_ty(self.ccx, dropped_ty) {
|
||||||
// Instead of throwing a bug, we just return here. This is because we have to
|
// Instead of throwing a bug, we just return here. This is because we have to
|
||||||
// run custom `const Drop` impls.
|
// run custom `const Drop` impls.
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -23,7 +23,8 @@ pub fn in_any_value_of_ty<'tcx>(
|
||||||
ConstQualifs {
|
ConstQualifs {
|
||||||
has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty),
|
has_mut_interior: HasMutInterior::in_any_value_of_ty(cx, ty),
|
||||||
needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
|
needs_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
|
||||||
needs_non_const_drop: NeedsNonConstDrop::in_any_value_of_ty(cx, ty),
|
// FIXME(effects)
|
||||||
|
needs_non_const_drop: NeedsDrop::in_any_value_of_ty(cx, ty),
|
||||||
custom_eq: CustomEq::in_any_value_of_ty(cx, ty),
|
custom_eq: CustomEq::in_any_value_of_ty(cx, ty),
|
||||||
tainted_by_errors,
|
tainted_by_errors,
|
||||||
}
|
}
|
||||||
|
|
|
@ -219,11 +219,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
// The key step here is to update the caller_bounds's predicates to be
|
// The key step here is to update the caller_bounds's predicates to be
|
||||||
// the new hybrid bounds we computed.
|
// the new hybrid bounds we computed.
|
||||||
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
|
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_def_id);
|
||||||
let param_env = ty::ParamEnv::new(
|
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing);
|
||||||
tcx.mk_clauses(&hybrid_preds.predicates),
|
|
||||||
Reveal::UserFacing,
|
|
||||||
hir::Constness::NotConst,
|
|
||||||
);
|
|
||||||
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
|
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
|
||||||
|
|
||||||
let infcx = &tcx.infer_ctxt().build();
|
let infcx = &tcx.infer_ctxt().build();
|
||||||
|
@ -1923,11 +1919,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
|
|
||||||
let impl_ty_span = tcx.def_span(impl_ty_def_id);
|
let impl_ty_span = tcx.def_span(impl_ty_def_id);
|
||||||
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
|
let normalize_cause = traits::ObligationCause::misc(impl_ty_span, impl_ty_def_id);
|
||||||
let param_env = ty::ParamEnv::new(
|
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds.predicates), Reveal::UserFacing);
|
||||||
tcx.mk_clauses(&hybrid_preds.predicates),
|
|
||||||
Reveal::UserFacing,
|
|
||||||
hir::Constness::NotConst,
|
|
||||||
);
|
|
||||||
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
|
let param_env = traits::normalize_param_env_or_error(tcx, param_env, normalize_cause);
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
@ -2102,7 +2094,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
.to_predicate(tcx),
|
.to_predicate(tcx),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing, param_env.constness())
|
ty::ParamEnv::new(tcx.mk_clauses(&predicates), Reveal::UserFacing)
|
||||||
};
|
};
|
||||||
debug!(?normalize_param_env);
|
debug!(?normalize_param_env);
|
||||||
|
|
||||||
|
|
|
@ -129,9 +129,8 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
|
||||||
// We don't need to normalize this param-env or anything, since we're only
|
// We don't need to normalize this param-env or anything, since we're only
|
||||||
// substituting it with free params, so no additional param-env normalization
|
// substituting it with free params, so no additional param-env normalization
|
||||||
// can occur on top of what has been done in the param_env query itself.
|
// can occur on top of what has been done in the param_env query itself.
|
||||||
let param_env = ty::EarlyBinder::bind(tcx.param_env(adt_def_id))
|
let param_env =
|
||||||
.instantiate(tcx, adt_to_impl_args)
|
ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args);
|
||||||
.with_constness(tcx.constness(drop_impl_def_id));
|
|
||||||
|
|
||||||
for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) {
|
for (pred, span) in tcx.predicates_of(drop_impl_def_id).instantiate_identity(tcx) {
|
||||||
let normalize_cause = traits::ObligationCause::misc(span, adt_def_id);
|
let normalize_cause = traits::ObligationCause::misc(span, adt_def_id);
|
||||||
|
|
|
@ -75,12 +75,10 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
self.body_def_id,
|
self.body_def_id,
|
||||||
ObligationCauseCode::WellFormed(loc),
|
ObligationCauseCode::WellFormed(loc),
|
||||||
);
|
);
|
||||||
// for a type to be WF, we do not need to check if const trait predicates satisfy.
|
|
||||||
let param_env = self.param_env.without_const();
|
|
||||||
self.ocx.register_obligation(traits::Obligation::new(
|
self.ocx.register_obligation(traits::Obligation::new(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
cause,
|
cause,
|
||||||
param_env,
|
self.param_env,
|
||||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg))),
|
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg))),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -504,7 +502,7 @@ fn augment_param_env<'tcx>(
|
||||||
);
|
);
|
||||||
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
|
// FIXME(compiler-errors): Perhaps there is a case where we need to normalize this
|
||||||
// i.e. traits::normalize_param_env_or_error
|
// i.e. traits::normalize_param_env_or_error
|
||||||
ty::ParamEnv::new(bounds, param_env.reveal(), param_env.constness())
|
ty::ParamEnv::new(bounds, param_env.reveal())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We use the following trait as an example throughout this function.
|
/// We use the following trait as an example throughout this function.
|
||||||
|
@ -1415,7 +1413,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| {
|
let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| {
|
||||||
traits::wf::predicate_obligations(
|
traits::wf::predicate_obligations(
|
||||||
infcx,
|
infcx,
|
||||||
wfcx.param_env.without_const(),
|
wfcx.param_env,
|
||||||
wfcx.body_def_id,
|
wfcx.body_def_id,
|
||||||
p.as_predicate(),
|
p.as_predicate(),
|
||||||
sp,
|
sp,
|
||||||
|
|
|
@ -81,7 +81,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
debug!(?bound_sig, ?liberated_sig);
|
debug!(?bound_sig, ?liberated_sig);
|
||||||
|
|
||||||
let mut fcx = FnCtxt::new(self, self.param_env.without_const(), closure.def_id);
|
let mut fcx = FnCtxt::new(self, self.param_env, closure.def_id);
|
||||||
let generator_types = check_fn(
|
let generator_types = check_fn(
|
||||||
&mut fcx,
|
&mut fcx,
|
||||||
liberated_sig,
|
liberated_sig,
|
||||||
|
|
|
@ -1334,7 +1334,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
t_cast,
|
t_cast,
|
||||||
t.span,
|
t.span,
|
||||||
expr.span,
|
expr.span,
|
||||||
self.param_env.constness(),
|
hir::Constness::NotConst,
|
||||||
) {
|
) {
|
||||||
Ok(cast_check) => {
|
Ok(cast_check) => {
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -1428,7 +1428,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
// Create a new function context.
|
// Create a new function context.
|
||||||
let def_id = block.def_id;
|
let def_id = block.def_id;
|
||||||
let fcx = FnCtxt::new(self, self.param_env.with_const(), def_id);
|
let fcx = FnCtxt::new(self, self.param_env, def_id);
|
||||||
crate::GatherLocalsVisitor::new(&fcx).visit_body(body);
|
crate::GatherLocalsVisitor::new(&fcx).visit_body(body);
|
||||||
|
|
||||||
let ty = fcx.check_expr_with_expectation(&body.value, expected);
|
let ty = fcx.check_expr_with_expectation(&body.value, expected);
|
||||||
|
|
|
@ -45,12 +45,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
|
|
||||||
debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
|
debug!("FnCtxt::check_casts: {} deferred checks", deferred_cast_checks.len());
|
||||||
for cast in deferred_cast_checks.drain(..) {
|
for cast in deferred_cast_checks.drain(..) {
|
||||||
let prev_env = self.param_env;
|
|
||||||
self.param_env = self.param_env.with_constness(cast.constness);
|
|
||||||
|
|
||||||
cast.check(self);
|
cast.check(self);
|
||||||
|
|
||||||
self.param_env = prev_env;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*self.deferred_cast_checks.borrow_mut() = deferred_cast_checks;
|
*self.deferred_cast_checks.borrow_mut() = deferred_cast_checks;
|
||||||
|
|
|
@ -71,7 +71,7 @@ use rustc_middle::traits;
|
||||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||||
use rustc_session::config;
|
use rustc_session::config;
|
||||||
use rustc_span::def_id::{DefId, LocalDefId};
|
use rustc_span::def_id::{DefId, LocalDefId};
|
||||||
use rustc_span::{sym, Span};
|
use rustc_span::Span;
|
||||||
|
|
||||||
fluent_messages! { "../messages.ftl" }
|
fluent_messages! { "../messages.ftl" }
|
||||||
|
|
||||||
|
@ -182,11 +182,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
let body = tcx.hir().body(body_id);
|
let body = tcx.hir().body(body_id);
|
||||||
|
|
||||||
let param_env = tcx.param_env(def_id);
|
let param_env = tcx.param_env(def_id);
|
||||||
let param_env = if tcx.has_attr(def_id, sym::rustc_do_not_const_check) {
|
|
||||||
param_env.without_const()
|
|
||||||
} else {
|
|
||||||
param_env
|
|
||||||
};
|
|
||||||
let inh = Inherited::new(tcx, def_id);
|
let inh = Inherited::new(tcx, def_id);
|
||||||
let mut fcx = FnCtxt::new(&inh, param_env, def_id);
|
let mut fcx = FnCtxt::new(&inh, param_env, def_id);
|
||||||
|
|
||||||
|
@ -263,11 +259,7 @@ fn typeck_with_fallback<'tcx>(
|
||||||
|
|
||||||
// Closure and generator analysis may run after fallback
|
// Closure and generator analysis may run after fallback
|
||||||
// because they don't constrain other type variables.
|
// because they don't constrain other type variables.
|
||||||
// Closure analysis only runs on closures. Therefore they only need to fulfill non-const predicates (as of now)
|
|
||||||
let prev_constness = fcx.param_env.constness();
|
|
||||||
fcx.param_env = fcx.param_env.without_const();
|
|
||||||
fcx.closure_analyze(body);
|
fcx.closure_analyze(body);
|
||||||
fcx.param_env = fcx.param_env.with_constness(prev_constness);
|
|
||||||
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
|
assert!(fcx.deferred_call_resolutions.borrow().is_empty());
|
||||||
// Before the generator analysis, temporary scopes shall be marked to provide more
|
// Before the generator analysis, temporary scopes shall be marked to provide more
|
||||||
// precise information on types to be captured.
|
// precise information on types to be captured.
|
||||||
|
|
|
@ -79,7 +79,6 @@ impl<'tcx> PredicateObligation<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
|
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
|
||||||
self.param_env = self.param_env.without_const();
|
|
||||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
|
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
|
||||||
self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const()))));
|
self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const()))));
|
||||||
}
|
}
|
||||||
|
@ -88,14 +87,6 @@ impl<'tcx> PredicateObligation<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> PolyTraitObligation<'tcx> {
|
impl<'tcx> PolyTraitObligation<'tcx> {
|
||||||
/// Returns `true` if the trait predicate is considered `const` in its ParamEnv.
|
|
||||||
pub fn is_const(&self) -> bool {
|
|
||||||
matches!(
|
|
||||||
(self.predicate.skip_binder().constness, self.param_env.constness()),
|
|
||||||
(ty::BoundConstness::ConstIfConst, hir::Constness::Const)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn derived_cause(
|
pub fn derived_cause(
|
||||||
&self,
|
&self,
|
||||||
variant: impl FnOnce(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>,
|
variant: impl FnOnce(DerivedObligationCause<'tcx>) -> ObligationCauseCode<'tcx>,
|
||||||
|
|
|
@ -139,7 +139,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
cid: GlobalId<'tcx>,
|
cid: GlobalId<'tcx>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> EvalToConstValueResult<'tcx> {
|
) -> EvalToConstValueResult<'tcx> {
|
||||||
let param_env = param_env.with_const();
|
|
||||||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||||
// improve caching of queries.
|
// improve caching of queries.
|
||||||
let inputs = self.erase_regions(param_env.and(cid));
|
let inputs = self.erase_regions(param_env.and(cid));
|
||||||
|
@ -158,8 +157,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||||
cid: GlobalId<'tcx>,
|
cid: GlobalId<'tcx>,
|
||||||
span: Option<Span>,
|
span: Option<Span>,
|
||||||
) -> EvalToValTreeResult<'tcx> {
|
) -> EvalToValTreeResult<'tcx> {
|
||||||
let param_env = param_env.with_const();
|
|
||||||
debug!(?param_env);
|
|
||||||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||||
// improve caching of queries.
|
// improve caching of queries.
|
||||||
let inputs = self.erase_regions(param_env.and(cid));
|
let inputs = self.erase_regions(param_env.and(cid));
|
||||||
|
@ -204,7 +201,6 @@ impl<'tcx> TyCtxtAt<'tcx> {
|
||||||
gid: GlobalId<'tcx>,
|
gid: GlobalId<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
|
) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
|
||||||
let param_env = param_env.with_const();
|
|
||||||
trace!("eval_to_allocation: Need to compute {:?}", gid);
|
trace!("eval_to_allocation: Need to compute {:?}", gid);
|
||||||
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
|
let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
|
||||||
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
|
Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
|
||||||
|
@ -224,8 +220,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
|
||||||
let args = GenericArgs::identity_for_item(self.tcx, def_id);
|
let args = GenericArgs::identity_for_item(self.tcx, def_id);
|
||||||
let instance = ty::Instance::new(def_id, args);
|
let instance = ty::Instance::new(def_id, args);
|
||||||
let cid = GlobalId { instance, promoted: None };
|
let cid = GlobalId { instance, promoted: None };
|
||||||
let param_env =
|
let param_env = self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx);
|
||||||
self.tcx.param_env(def_id).with_reveal_all_normalized(self.tcx).with_const();
|
|
||||||
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
// Const-eval shouldn't depend on lifetimes at all, so we can erase them, which should
|
||||||
// improve caching of queries.
|
// improve caching of queries.
|
||||||
let inputs = self.tcx.erase_regions(param_env.and(cid));
|
let inputs = self.tcx.erase_regions(param_env.and(cid));
|
||||||
|
@ -238,7 +233,7 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
|
||||||
assert!(self.tcx.is_static(def_id));
|
assert!(self.tcx.is_static(def_id));
|
||||||
let instance = ty::Instance::mono(self.tcx, def_id);
|
let instance = ty::Instance::mono(self.tcx, def_id);
|
||||||
let gid = GlobalId { instance, promoted: None };
|
let gid = GlobalId { instance, promoted: None };
|
||||||
let param_env = ty::ParamEnv::reveal_all().with_const();
|
let param_env = ty::ParamEnv::reveal_all();
|
||||||
trace!("eval_to_allocation: Need to compute {:?}", gid);
|
trace!("eval_to_allocation: Need to compute {:?}", gid);
|
||||||
self.eval_to_allocation_raw(param_env.and(gid))
|
self.eval_to_allocation_raw(param_env.and(gid))
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,6 @@ impl<'tcx, E: TyEncoder<I = TyCtxt<'tcx>>> Encodable<E> for ty::ParamEnv<'tcx> {
|
||||||
fn encode(&self, e: &mut E) {
|
fn encode(&self, e: &mut E) {
|
||||||
self.caller_bounds().encode(e);
|
self.caller_bounds().encode(e);
|
||||||
self.reveal().encode(e);
|
self.reveal().encode(e);
|
||||||
self.constness().encode(e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -306,8 +305,7 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for ty::ParamEnv<'tcx> {
|
||||||
fn decode(d: &mut D) -> Self {
|
fn decode(d: &mut D) -> Self {
|
||||||
let caller_bounds = Decodable::decode(d);
|
let caller_bounds = Decodable::decode(d);
|
||||||
let reveal = Decodable::decode(d);
|
let reveal = Decodable::decode(d);
|
||||||
let constness = Decodable::decode(d);
|
ty::ParamEnv::new(caller_bounds, reveal)
|
||||||
ty::ParamEnv::new(caller_bounds, reveal, constness)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -867,20 +867,6 @@ pub struct TraitPredicate<'tcx> {
|
||||||
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
||||||
|
|
||||||
impl<'tcx> TraitPredicate<'tcx> {
|
impl<'tcx> TraitPredicate<'tcx> {
|
||||||
pub fn remap_constness(&mut self, param_env: &mut ParamEnv<'tcx>) {
|
|
||||||
*param_env = param_env.with_constness(self.constness.and(param_env.constness()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remap the constness of this predicate before emitting it for diagnostics.
|
|
||||||
pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
|
|
||||||
// this is different to `remap_constness` that callees want to print this predicate
|
|
||||||
// in case of selection errors. `T: ~const Drop` bounds cannot end up here when the
|
|
||||||
// param_env is not const because it is always satisfied in non-const contexts.
|
|
||||||
if let hir::Constness::NotConst = param_env.constness() {
|
|
||||||
self.constness = ty::BoundConstness::NotConst;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
||||||
Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self }
|
Self { trait_ref: self.trait_ref.with_self_ty(tcx, self_ty), ..self }
|
||||||
}
|
}
|
||||||
|
@ -922,14 +908,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||||
self.map_bound(|trait_ref| trait_ref.self_ty())
|
self.map_bound(|trait_ref| trait_ref.self_ty())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remap the constness of this predicate before emitting it for diagnostics.
|
|
||||||
pub fn remap_constness_diag(&mut self, param_env: ParamEnv<'tcx>) {
|
|
||||||
*self = self.map_bound(|mut p| {
|
|
||||||
p.remap_constness_diag(param_env);
|
|
||||||
p
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_const_if_const(self) -> bool {
|
pub fn is_const_if_const(self) -> bool {
|
||||||
self.skip_binder().is_const_if_const()
|
self.skip_binder().is_const_if_const()
|
||||||
|
@ -1700,15 +1678,12 @@ pub struct ParamEnv<'tcx> {
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
struct ParamTag {
|
struct ParamTag {
|
||||||
reveal: traits::Reveal,
|
reveal: traits::Reveal,
|
||||||
constness: hir::Constness,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_tag! {
|
impl_tag! {
|
||||||
impl Tag for ParamTag;
|
impl Tag for ParamTag;
|
||||||
ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::NotConst },
|
ParamTag { reveal: traits::Reveal::UserFacing },
|
||||||
ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::NotConst },
|
ParamTag { reveal: traits::Reveal::All },
|
||||||
ParamTag { reveal: traits::Reveal::UserFacing, constness: hir::Constness::Const },
|
|
||||||
ParamTag { reveal: traits::Reveal::All, constness: hir::Constness::Const },
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
|
impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
|
||||||
|
@ -1716,7 +1691,6 @@ impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
|
||||||
f.debug_struct("ParamEnv")
|
f.debug_struct("ParamEnv")
|
||||||
.field("caller_bounds", &self.caller_bounds())
|
.field("caller_bounds", &self.caller_bounds())
|
||||||
.field("reveal", &self.reveal())
|
.field("reveal", &self.reveal())
|
||||||
.field("constness", &self.constness())
|
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1725,7 +1699,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||||
self.caller_bounds().hash_stable(hcx, hasher);
|
self.caller_bounds().hash_stable(hcx, hasher);
|
||||||
self.reveal().hash_stable(hcx, hasher);
|
self.reveal().hash_stable(hcx, hasher);
|
||||||
self.constness().hash_stable(hcx, hasher);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1737,7 +1710,6 @@ impl<'tcx> TypeFoldable<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
||||||
Ok(ParamEnv::new(
|
Ok(ParamEnv::new(
|
||||||
self.caller_bounds().try_fold_with(folder)?,
|
self.caller_bounds().try_fold_with(folder)?,
|
||||||
self.reveal().try_fold_with(folder)?,
|
self.reveal().try_fold_with(folder)?,
|
||||||
self.constness(),
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1756,7 +1728,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
/// type-checking.
|
/// type-checking.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
Self::new(List::empty(), Reveal::UserFacing, hir::Constness::NotConst)
|
Self::new(List::empty(), Reveal::UserFacing)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -1769,16 +1741,6 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
self.packed.tag().reveal
|
self.packed.tag().reveal
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn constness(self) -> hir::Constness {
|
|
||||||
self.packed.tag().constness
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn is_const(self) -> bool {
|
|
||||||
self.packed.tag().constness == hir::Constness::Const
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Construct a trait environment with no where-clauses in scope
|
/// Construct a trait environment with no where-clauses in scope
|
||||||
/// where the values of all `impl Trait` and other hidden types
|
/// where the values of all `impl Trait` and other hidden types
|
||||||
/// are revealed. This is suitable for monomorphized, post-typeck
|
/// are revealed. This is suitable for monomorphized, post-typeck
|
||||||
|
@ -1788,17 +1750,13 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
/// or invoke `param_env.with_reveal_all()`.
|
/// or invoke `param_env.with_reveal_all()`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reveal_all() -> Self {
|
pub fn reveal_all() -> Self {
|
||||||
Self::new(List::empty(), Reveal::All, hir::Constness::NotConst)
|
Self::new(List::empty(), Reveal::All)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a trait environment with the given set of predicates.
|
/// Construct a trait environment with the given set of predicates.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(
|
pub fn new(caller_bounds: &'tcx List<Clause<'tcx>>, reveal: Reveal) -> Self {
|
||||||
caller_bounds: &'tcx List<Clause<'tcx>>,
|
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal }) }
|
||||||
reveal: Reveal,
|
|
||||||
constness: hir::Constness,
|
|
||||||
) -> Self {
|
|
||||||
ty::ParamEnv { packed: CopyTaggedPtr::new(caller_bounds, ParamTag { reveal, constness }) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_user_facing(mut self) -> Self {
|
pub fn with_user_facing(mut self) -> Self {
|
||||||
|
@ -1806,29 +1764,6 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn with_constness(mut self, constness: hir::Constness) -> Self {
|
|
||||||
self.packed.set_tag(ParamTag { constness, ..self.packed.tag() });
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn with_const(mut self) -> Self {
|
|
||||||
self.packed.set_tag(ParamTag { constness: hir::Constness::Const, ..self.packed.tag() });
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn without_const(mut self) -> Self {
|
|
||||||
self.packed.set_tag(ParamTag { constness: hir::Constness::NotConst, ..self.packed.tag() });
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn remap_constness_with(&mut self, mut constness: ty::BoundConstness) {
|
|
||||||
*self = self.with_constness(constness.and(self.constness()))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a new parameter environment with the same clauses, but
|
/// Returns a new parameter environment with the same clauses, but
|
||||||
/// which "reveals" the true results of projections in all cases
|
/// which "reveals" the true results of projections in all cases
|
||||||
/// (even for associated types that are specializable). This is
|
/// (even for associated types that are specializable). This is
|
||||||
|
@ -1843,17 +1778,13 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParamEnv::new(
|
ParamEnv::new(tcx.reveal_opaque_types_in_bounds(self.caller_bounds()), Reveal::All)
|
||||||
tcx.reveal_opaque_types_in_bounds(self.caller_bounds()),
|
|
||||||
Reveal::All,
|
|
||||||
self.constness(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns this same environment but with no caller bounds.
|
/// Returns this same environment but with no caller bounds.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn without_caller_bounds(self) -> Self {
|
pub fn without_caller_bounds(self) -> Self {
|
||||||
Self::new(List::empty(), self.reveal(), self.constness())
|
Self::new(List::empty(), self.reveal())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a suitable environment in which to perform trait
|
/// Creates a suitable environment in which to perform trait
|
||||||
|
|
|
@ -602,7 +602,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
|
||||||
type Lifted = ty::ParamEnv<'tcx>;
|
type Lifted = ty::ParamEnv<'tcx>;
|
||||||
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||||
tcx.lift(self.caller_bounds())
|
tcx.lift(self.caller_bounds())
|
||||||
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.constness()))
|
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -449,14 +449,11 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||||
return Err(NoSolution);
|
return Err(NoSolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !goal.param_env.is_const() {
|
// FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
|
||||||
// `Destruct` is automatically implemented for every type in
|
|
||||||
// non-const environments.
|
// `Destruct` is automatically implemented for every type in
|
||||||
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
// non-const environments.
|
||||||
} else {
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
// FIXME(-Ztrait-solver=next): Implement this when we get const working in the new solver
|
|
||||||
Err(NoSolution)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn consider_builtin_transmute_candidate(
|
fn consider_builtin_transmute_candidate(
|
||||||
|
|
|
@ -347,14 +347,12 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
new_env = ty::ParamEnv::new(
|
new_env = ty::ParamEnv::new(
|
||||||
tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
|
tcx.mk_clauses_from_iter(normalized_preds.filter_map(|p| p.as_clause())),
|
||||||
param_env.reveal(),
|
param_env.reveal(),
|
||||||
param_env.constness(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let final_user_env = ty::ParamEnv::new(
|
let final_user_env = ty::ParamEnv::new(
|
||||||
tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())),
|
tcx.mk_clauses_from_iter(user_computed_preds.into_iter().filter_map(|p| p.as_clause())),
|
||||||
user_env.reveal(),
|
user_env.reveal(),
|
||||||
user_env.constness(),
|
|
||||||
);
|
);
|
||||||
debug!(
|
debug!(
|
||||||
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
|
"evaluate_nested_obligations(ty={:?}, trait_did={:?}): succeeded with '{:?}' \
|
||||||
|
|
|
@ -687,9 +687,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
match bound_predicate.skip_binder() {
|
match bound_predicate.skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => {
|
||||||
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
||||||
let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate);
|
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
|
||||||
|
|
||||||
trait_predicate.remap_constness_diag(obligation.param_env);
|
|
||||||
let predicate_is_const = ty::BoundConstness::ConstIfConst
|
let predicate_is_const = ty::BoundConstness::ConstIfConst
|
||||||
== trait_predicate.skip_binder().constness;
|
== trait_predicate.skip_binder().constness;
|
||||||
|
|
||||||
|
@ -3108,11 +3107,11 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
span: Span,
|
span: Span,
|
||||||
) -> UnsatisfiedConst {
|
) -> UnsatisfiedConst {
|
||||||
let mut unsatisfied_const = UnsatisfiedConst(false);
|
let mut unsatisfied_const = UnsatisfiedConst(false);
|
||||||
if trait_predicate.is_const_if_const() && obligation.param_env.is_const() {
|
if trait_predicate.is_const_if_const() {
|
||||||
let non_const_predicate = trait_ref.without_const();
|
let non_const_predicate = trait_ref.without_const();
|
||||||
let non_const_obligation = Obligation {
|
let non_const_obligation = Obligation {
|
||||||
cause: obligation.cause.clone(),
|
cause: obligation.cause.clone(),
|
||||||
param_env: obligation.param_env.without_const(),
|
param_env: obligation.param_env,
|
||||||
predicate: non_const_predicate.to_predicate(self.tcx),
|
predicate: non_const_predicate.to_predicate(self.tcx),
|
||||||
recursion_depth: obligation.recursion_depth,
|
recursion_depth: obligation.recursion_depth,
|
||||||
};
|
};
|
||||||
|
|
|
@ -3136,7 +3136,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||||
ObligationCauseCode::ImplDerivedObligation(ref data) => {
|
ObligationCauseCode::ImplDerivedObligation(ref data) => {
|
||||||
let mut parent_trait_pred =
|
let mut parent_trait_pred =
|
||||||
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
|
self.resolve_vars_if_possible(data.derived.parent_trait_pred);
|
||||||
parent_trait_pred.remap_constness_diag(param_env);
|
|
||||||
let parent_def_id = parent_trait_pred.def_id();
|
let parent_def_id = parent_trait_pred.def_id();
|
||||||
let (self_ty, file) =
|
let (self_ty, file) =
|
||||||
self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
|
self.tcx.short_ty_string(parent_trait_pred.skip_binder().self_ty());
|
||||||
|
|
|
@ -328,11 +328,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
|
|
||||||
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
|
||||||
|
|
||||||
let elaborated_env = ty::ParamEnv::new(
|
let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
|
||||||
tcx.mk_clauses(&predicates),
|
|
||||||
unnormalized_env.reveal(),
|
|
||||||
unnormalized_env.constness(),
|
|
||||||
);
|
|
||||||
|
|
||||||
// HACK: we are trying to normalize the param-env inside *itself*. The problem is that
|
// HACK: we are trying to normalize the param-env inside *itself*. The problem is that
|
||||||
// normalization expects its param-env to be already normalized, which means we have
|
// normalization expects its param-env to be already normalized, which means we have
|
||||||
|
@ -376,11 +372,8 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
// here. I believe they should not matter, because we are ignoring TypeOutlives param-env
|
// here. I believe they should not matter, because we are ignoring TypeOutlives param-env
|
||||||
// predicates here anyway. Keeping them here anyway because it seems safer.
|
// predicates here anyway. Keeping them here anyway because it seems safer.
|
||||||
let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
|
let outlives_env = non_outlives_predicates.iter().chain(&outlives_predicates).cloned();
|
||||||
let outlives_env = ty::ParamEnv::new(
|
let outlives_env =
|
||||||
tcx.mk_clauses_from_iter(outlives_env),
|
ty::ParamEnv::new(tcx.mk_clauses_from_iter(outlives_env), unnormalized_env.reveal());
|
||||||
unnormalized_env.reveal(),
|
|
||||||
unnormalized_env.constness(),
|
|
||||||
);
|
|
||||||
let Ok(outlives_predicates) =
|
let Ok(outlives_predicates) =
|
||||||
do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates)
|
do_normalize_predicates(tcx, cause, outlives_env, outlives_predicates)
|
||||||
else {
|
else {
|
||||||
|
@ -393,11 +386,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
||||||
let mut predicates = non_outlives_predicates;
|
let mut predicates = non_outlives_predicates;
|
||||||
predicates.extend(outlives_predicates);
|
predicates.extend(outlives_predicates);
|
||||||
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
||||||
ty::ParamEnv::new(
|
ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal())
|
||||||
tcx.mk_clauses(&predicates),
|
|
||||||
unnormalized_env.reveal(),
|
|
||||||
unnormalized_env.constness(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Normalize a type and process all resulting obligations, returning any errors.
|
/// Normalize a type and process all resulting obligations, returning any errors.
|
||||||
|
|
|
@ -761,11 +761,7 @@ fn receiver_is_dispatchable<'tcx>(
|
||||||
let caller_bounds =
|
let caller_bounds =
|
||||||
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
|
param_env.caller_bounds().iter().chain([unsize_predicate, trait_predicate]);
|
||||||
|
|
||||||
ty::ParamEnv::new(
|
ty::ParamEnv::new(tcx.mk_clauses_from_iter(caller_bounds), param_env.reveal())
|
||||||
tcx.mk_clauses_from_iter(caller_bounds),
|
|
||||||
param_env.reveal(),
|
|
||||||
param_env.constness(),
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use rustc_infer::traits::{TraitEngine, TraitEngineExt};
|
use rustc_infer::traits::{TraitEngine, TraitEngineExt};
|
||||||
use rustc_middle::ty;
|
|
||||||
|
|
||||||
use crate::infer::canonical::OriginalQueryValues;
|
use crate::infer::canonical::OriginalQueryValues;
|
||||||
use crate::infer::InferCtxt;
|
use crate::infer::InferCtxt;
|
||||||
|
@ -66,17 +65,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||||
) -> Result<EvaluationResult, OverflowError> {
|
) -> Result<EvaluationResult, OverflowError> {
|
||||||
let mut _orig_values = OriginalQueryValues::default();
|
let mut _orig_values = OriginalQueryValues::default();
|
||||||
|
|
||||||
let param_env = match obligation.predicate.kind().skip_binder() {
|
let param_env = obligation.param_env;
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) => {
|
|
||||||
// we ignore the value set to it.
|
|
||||||
let mut _constness = pred.constness;
|
|
||||||
obligation
|
|
||||||
.param_env
|
|
||||||
.with_constness(_constness.and(obligation.param_env.constness()))
|
|
||||||
}
|
|
||||||
// constness has no effect on the given predicate.
|
|
||||||
_ => obligation.param_env.without_const(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if self.next_trait_solver() {
|
if self.next_trait_solver() {
|
||||||
self.probe(|snapshot| {
|
self.probe(|snapshot| {
|
||||||
|
|
|
@ -82,7 +82,6 @@ fn relate_mir_and_user_args<'tcx>(
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
user_args: UserArgs<'tcx>,
|
user_args: UserArgs<'tcx>,
|
||||||
) -> Result<(), NoSolution> {
|
) -> Result<(), NoSolution> {
|
||||||
let param_env = param_env.without_const();
|
|
||||||
let UserArgs { user_self_ty, args } = user_args;
|
let UserArgs { user_self_ty, args } = user_args;
|
||||||
let tcx = ocx.infcx.tcx;
|
let tcx = ocx.infcx.tcx;
|
||||||
let cause = ObligationCause::dummy_with_span(span);
|
let cause = ObligationCause::dummy_with_span(span);
|
||||||
|
|
|
@ -839,7 +839,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
) {
|
) {
|
||||||
// If the predicate is `~const Destruct` in a non-const environment, we don't actually need
|
// If the predicate is `~const Destruct` in a non-const environment, we don't actually need
|
||||||
// to check anything. We'll short-circuit checking any obligations in confirmation, too.
|
// to check anything. We'll short-circuit checking any obligations in confirmation, too.
|
||||||
if !obligation.is_const() {
|
// FIXME(effects)
|
||||||
|
if true {
|
||||||
candidates.vec.push(ConstDestructCandidate(None));
|
candidates.vec.push(ConstDestructCandidate(None));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,8 @@ use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||||
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
|
use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
|
||||||
use rustc_middle::traits::{BuiltinImplSource, SelectionOutputTypeParameterMismatch};
|
use rustc_middle::traits::{BuiltinImplSource, SelectionOutputTypeParameterMismatch};
|
||||||
use rustc_middle::ty::{
|
use rustc_middle::ty::{
|
||||||
self, Binder, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
|
self, GenericArgs, GenericArgsRef, GenericParamDefKind, ToPolyTraitRef, ToPredicate,
|
||||||
TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt,
|
TraitPredicate, Ty, TyCtxt, TypeVisitableExt,
|
||||||
};
|
};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
|
|
||||||
|
@ -647,7 +647,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
fn confirm_fn_pointer_candidate(
|
fn confirm_fn_pointer_candidate(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &PolyTraitObligation<'tcx>,
|
obligation: &PolyTraitObligation<'tcx>,
|
||||||
is_const: bool,
|
// FIXME(effects)
|
||||||
|
_is_const: bool,
|
||||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||||
debug!(?obligation, "confirm_fn_pointer_candidate");
|
debug!(?obligation, "confirm_fn_pointer_candidate");
|
||||||
|
|
||||||
|
@ -674,16 +675,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
|
let mut nested = self.confirm_poly_trait_refs(obligation, trait_ref)?;
|
||||||
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
let cause = obligation.derived_cause(BuiltinDerivedObligation);
|
||||||
|
|
||||||
if obligation.is_const() && !is_const {
|
|
||||||
// function is a trait method
|
|
||||||
if let ty::FnDef(def_id, args) = self_ty.kind() && let Some(trait_id) = tcx.trait_of_item(*def_id) {
|
|
||||||
let trait_ref = TraitRef::from_method(tcx, trait_id, *args);
|
|
||||||
let poly_trait_pred = Binder::dummy(trait_ref).with_constness(ty::BoundConstness::ConstIfConst);
|
|
||||||
let obligation = Obligation::new(tcx, cause.clone(), obligation.param_env, poly_trait_pred);
|
|
||||||
nested.push(obligation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
|
// Confirm the `type Output: Sized;` bound that is present on `FnOnce`
|
||||||
let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output());
|
let output_ty = self.infcx.instantiate_binder_with_placeholders(sig.output());
|
||||||
let output_ty = normalize_with_depth_to(
|
let output_ty = normalize_with_depth_to(
|
||||||
|
@ -1211,7 +1202,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
impl_def_id: Option<DefId>,
|
impl_def_id: Option<DefId>,
|
||||||
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
) -> Result<Vec<PredicateObligation<'tcx>>, SelectionError<'tcx>> {
|
||||||
// `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
|
// `~const Destruct` in a non-const environment is always trivially true, since our type is `Drop`
|
||||||
if !obligation.is_const() {
|
// FIXME(effects)
|
||||||
|
if true {
|
||||||
return Ok(vec![]);
|
return Ok(vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1000,13 +1000,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let stack = self.push_stack(previous_stack, &obligation);
|
let stack = self.push_stack(previous_stack, &obligation);
|
||||||
let mut fresh_trait_pred = stack.fresh_trait_pred;
|
let fresh_trait_pred = stack.fresh_trait_pred;
|
||||||
let mut param_env = obligation.param_env;
|
let param_env = obligation.param_env;
|
||||||
|
|
||||||
fresh_trait_pred = fresh_trait_pred.map_bound(|mut pred| {
|
|
||||||
pred.remap_constness(&mut param_env);
|
|
||||||
pred
|
|
||||||
});
|
|
||||||
|
|
||||||
debug!(?fresh_trait_pred);
|
debug!(?fresh_trait_pred);
|
||||||
|
|
||||||
|
@ -1386,8 +1381,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
(result, dep_node)
|
(result, dep_node)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// filter_impls filters constant trait obligations and candidates that have a positive impl
|
/// filter_impls filters candidates that have a positive impl for a negative
|
||||||
/// for a negative goal and a negative impl for a positive goal
|
/// goal and a negative impl for a positive goal
|
||||||
#[instrument(level = "debug", skip(self, candidates))]
|
#[instrument(level = "debug", skip(self, candidates))]
|
||||||
fn filter_impls(
|
fn filter_impls(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
@ -1399,42 +1394,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
let mut result = Vec::with_capacity(candidates.len());
|
let mut result = Vec::with_capacity(candidates.len());
|
||||||
|
|
||||||
for candidate in candidates {
|
for candidate in candidates {
|
||||||
// Respect const trait obligations
|
|
||||||
if obligation.is_const() {
|
|
||||||
match candidate {
|
|
||||||
// const impl
|
|
||||||
ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
|
|
||||||
// const param
|
|
||||||
ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
|
|
||||||
// const projection
|
|
||||||
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst)
|
|
||||||
// auto trait impl
|
|
||||||
| AutoImplCandidate
|
|
||||||
// generator / future, this will raise error in other places
|
|
||||||
// or ignore error with const_async_blocks feature
|
|
||||||
| GeneratorCandidate
|
|
||||||
| FutureCandidate
|
|
||||||
// FnDef where the function is const
|
|
||||||
| FnPointerCandidate { is_const: true }
|
|
||||||
| ConstDestructCandidate(_)
|
|
||||||
| ClosureCandidate { is_const: true } => {}
|
|
||||||
|
|
||||||
FnPointerCandidate { is_const: false } => {
|
|
||||||
if let ty::FnDef(def_id, _) = obligation.self_ty().skip_binder().kind() && tcx.trait_of_item(*def_id).is_some() {
|
|
||||||
// Trait methods are not seen as const unless the trait is implemented as const.
|
|
||||||
// We do not filter that out in here, but nested obligations will be needed to confirm this.
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_ => {
|
|
||||||
// reject all other types of candidates
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let ImplCandidate(def_id) = candidate {
|
if let ImplCandidate(def_id) = candidate {
|
||||||
if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id)
|
if ty::ImplPolarity::Reservation == tcx.impl_polarity(def_id)
|
||||||
|| obligation.polarity() == tcx.impl_polarity(def_id)
|
|| obligation.polarity() == tcx.impl_polarity(def_id)
|
||||||
|
@ -1528,7 +1487,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
|
||||||
fn check_candidate_cache(
|
fn check_candidate_cache(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
|
) -> Option<SelectionResult<'tcx, SelectionCandidate<'tcx>>> {
|
||||||
// Neither the global nor local cache is aware of intercrate
|
// Neither the global nor local cache is aware of intercrate
|
||||||
|
@ -1539,8 +1498,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let mut pred = cache_fresh_trait_pred.skip_binder();
|
let pred = cache_fresh_trait_pred.skip_binder();
|
||||||
pred.remap_constness(&mut param_env);
|
|
||||||
|
|
||||||
if self.can_use_global_caches(param_env) {
|
if self.can_use_global_caches(param_env) {
|
||||||
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
|
if let Some(res) = tcx.selection_cache.get(&(param_env, pred), tcx) {
|
||||||
|
@ -1586,15 +1544,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
#[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")]
|
#[instrument(skip(self, param_env, cache_fresh_trait_pred, dep_node), level = "debug")]
|
||||||
fn insert_candidate_cache(
|
fn insert_candidate_cache(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
cache_fresh_trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||||
dep_node: DepNodeIndex,
|
dep_node: DepNodeIndex,
|
||||||
candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>,
|
candidate: SelectionResult<'tcx, SelectionCandidate<'tcx>>,
|
||||||
) {
|
) {
|
||||||
let tcx = self.tcx();
|
let tcx = self.tcx();
|
||||||
let mut pred = cache_fresh_trait_pred.skip_binder();
|
let pred = cache_fresh_trait_pred.skip_binder();
|
||||||
|
|
||||||
pred.remap_constness(&mut param_env);
|
|
||||||
|
|
||||||
if !self.can_cache_candidate(&candidate) {
|
if !self.can_cache_candidate(&candidate) {
|
||||||
debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable");
|
debug!(?pred, ?candidate, "insert_candidate_cache - candidate is not cacheable");
|
||||||
|
|
|
@ -144,85 +144,9 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let local_did = def_id.as_local();
|
let local_did = def_id.as_local();
|
||||||
// FIXME(-Zlower-impl-trait-in-trait-to-assoc-ty): This isn't correct for
|
|
||||||
// RPITITs in const trait fn.
|
|
||||||
let hir_id = local_did.and_then(|def_id| tcx.opt_local_def_id_to_hir_id(def_id));
|
|
||||||
|
|
||||||
// FIXME(consts): This is not exactly in line with the constness query.
|
|
||||||
let constness = match hir_id {
|
|
||||||
Some(hir_id) => match tcx.hir().get(hir_id) {
|
|
||||||
hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Fn(..), .. })
|
|
||||||
if tcx.is_const_default_method(def_id) =>
|
|
||||||
{
|
|
||||||
hir::Constness::Const
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. })
|
|
||||||
| hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. })
|
|
||||||
| hir::Node::TraitItem(hir::TraitItem {
|
|
||||||
kind: hir::TraitItemKind::Const(..), ..
|
|
||||||
})
|
|
||||||
| hir::Node::AnonConst(_)
|
|
||||||
| hir::Node::ConstBlock(_)
|
|
||||||
| hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. })
|
|
||||||
| hir::Node::ImplItem(hir::ImplItem {
|
|
||||||
kind:
|
|
||||||
hir::ImplItemKind::Fn(
|
|
||||||
hir::FnSig {
|
|
||||||
header: hir::FnHeader { constness: hir::Constness::Const, .. },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..,
|
|
||||||
),
|
|
||||||
..
|
|
||||||
}) => hir::Constness::Const,
|
|
||||||
|
|
||||||
hir::Node::ImplItem(hir::ImplItem {
|
|
||||||
kind: hir::ImplItemKind::Type(..) | hir::ImplItemKind::Fn(..),
|
|
||||||
..
|
|
||||||
}) => {
|
|
||||||
let parent_hir_id = tcx.hir().parent_id(hir_id);
|
|
||||||
match tcx.hir().get(parent_hir_id) {
|
|
||||||
hir::Node::Item(hir::Item {
|
|
||||||
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
|
|
||||||
..
|
|
||||||
}) => *constness,
|
|
||||||
_ => span_bug!(
|
|
||||||
tcx.def_span(parent_hir_id.owner),
|
|
||||||
"impl item's parent node is not an impl",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hir::Node::Item(hir::Item {
|
|
||||||
kind:
|
|
||||||
hir::ItemKind::Fn(hir::FnSig { header: hir::FnHeader { constness, .. }, .. }, ..),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| hir::Node::TraitItem(hir::TraitItem {
|
|
||||||
kind:
|
|
||||||
hir::TraitItemKind::Fn(
|
|
||||||
hir::FnSig { header: hir::FnHeader { constness, .. }, .. },
|
|
||||||
..,
|
|
||||||
),
|
|
||||||
..
|
|
||||||
})
|
|
||||||
| hir::Node::Item(hir::Item {
|
|
||||||
kind: hir::ItemKind::Impl(hir::Impl { constness, .. }),
|
|
||||||
..
|
|
||||||
}) => *constness,
|
|
||||||
|
|
||||||
_ => hir::Constness::NotConst,
|
|
||||||
},
|
|
||||||
// FIXME(consts): It's suspicious that a param-env for a foreign item
|
|
||||||
// will always have NotConst param-env, though we don't typically use
|
|
||||||
// that param-env for anything meaningful right now, so it's likely
|
|
||||||
// not an issue.
|
|
||||||
None => hir::Constness::NotConst,
|
|
||||||
};
|
|
||||||
|
|
||||||
let unnormalized_env =
|
let unnormalized_env =
|
||||||
ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing, constness);
|
ty::ParamEnv::new(tcx.mk_clauses(&predicates), traits::Reveal::UserFacing);
|
||||||
|
|
||||||
let body_id = local_did.unwrap_or(CRATE_DEF_ID);
|
let body_id = local_did.unwrap_or(CRATE_DEF_ID);
|
||||||
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
|
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
|
||||||
|
|
|
@ -6,7 +6,7 @@ use rustc_errors::Applicability;
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
|
use rustc_hir::intravisit::{walk_expr, walk_fn, walk_item, FnKind, Visitor};
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
self as hir, BlockCheckMode, BodyId, Constness, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource,
|
self as hir, BlockCheckMode, BodyId, Expr, ExprKind, FnDecl, Impl, Item, ItemKind, UnsafeSource,
|
||||||
Unsafety,
|
Unsafety,
|
||||||
};
|
};
|
||||||
use rustc_lint::{LateContext, LateLintPass};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
|
@ -526,6 +526,5 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
|
||||||
}),
|
}),
|
||||||
)),
|
)),
|
||||||
Reveal::UserFacing,
|
Reveal::UserFacing,
|
||||||
Constness::NotConst,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
||||||
use clippy_utils::source::snippet_opt;
|
use clippy_utils::source::snippet_opt;
|
||||||
use clippy_utils::{is_from_proc_macro, path_to_local};
|
use clippy_utils::{is_from_proc_macro, path_to_local};
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::{BinOpKind, Expr, ExprKind};
|
use rustc_hir::{BinOpKind, Constness, Expr, ExprKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, Lint, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
use rustc_middle::lint::in_external_macro;
|
||||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
@ -83,8 +83,10 @@ impl Variant {
|
||||||
impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
impl<'tcx> LateLintPass<'tcx> for ManualFloatMethods {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
|
||||||
if !in_external_macro(cx.sess(), expr.span)
|
if !in_external_macro(cx.sess(), expr.span)
|
||||||
&& (!cx.param_env.is_const() || cx.tcx.features().active(sym!(const_float_classify)))
|
&& (
|
||||||
&& let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
matches!(cx.tcx.constness(cx.tcx.hir().enclosing_body_owner(expr.hir_id)), Constness::NotConst)
|
||||||
|
|| cx.tcx.features().active(sym!(const_float_classify))
|
||||||
|
) && let ExprKind::Binary(kind, lhs, rhs) = expr.kind
|
||||||
&& let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.kind
|
&& let ExprKind::Binary(lhs_kind, lhs_lhs, lhs_rhs) = lhs.kind
|
||||||
&& let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind
|
&& let ExprKind::Binary(rhs_kind, rhs_lhs, rhs_rhs) = rhs.kind
|
||||||
// Checking all possible scenarios using a function would be a hopeless task, as we have
|
// Checking all possible scenarios using a function would be a hopeless task, as we have
|
||||||
|
|
|
@ -391,32 +391,38 @@ fn is_const_fn(tcx: TyCtxt<'_>, def_id: DefId, msrv: &Msrv) -> bool {
|
||||||
|
|
||||||
#[expect(clippy::similar_names)] // bit too pedantic
|
#[expect(clippy::similar_names)] // bit too pedantic
|
||||||
fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
|
fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
|
||||||
// Avoid selecting for simple cases, such as builtin types.
|
// FIXME(effects, fee1-dead) revert to const destruct once it works again
|
||||||
if ty::util::is_trivially_const_drop(ty) {
|
#[expect(unused)]
|
||||||
return true;
|
fn is_ty_const_destruct_unused<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>) -> bool {
|
||||||
|
// Avoid selecting for simple cases, such as builtin types.
|
||||||
|
if ty::util::is_trivially_const_drop(ty) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let obligation = Obligation::new(
|
||||||
|
tcx,
|
||||||
|
ObligationCause::dummy_with_span(body.span),
|
||||||
|
ConstCx::new(tcx, body).param_env,
|
||||||
|
TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]).with_constness(BoundConstness::ConstIfConst),
|
||||||
|
);
|
||||||
|
|
||||||
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
let mut selcx = SelectionContext::new(&infcx);
|
||||||
|
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if !matches!(
|
||||||
|
impl_src,
|
||||||
|
ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(ty::BoundConstness::ConstIfConst, _)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let ocx = ObligationCtxt::new(&infcx);
|
||||||
|
ocx.register_obligations(impl_src.nested_obligations());
|
||||||
|
ocx.select_all_or_error().is_empty()
|
||||||
}
|
}
|
||||||
|
|
||||||
let obligation = Obligation::new(
|
!ty.needs_drop(tcx, ConstCx::new(tcx, body).param_env)
|
||||||
tcx,
|
|
||||||
ObligationCause::dummy_with_span(body.span),
|
|
||||||
ConstCx::new(tcx, body).param_env.with_const(),
|
|
||||||
TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]).with_constness(BoundConstness::ConstIfConst),
|
|
||||||
);
|
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
|
||||||
let mut selcx = SelectionContext::new(&infcx);
|
|
||||||
let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
if !matches!(
|
|
||||||
impl_src,
|
|
||||||
ImplSource::Builtin(BuiltinImplSource::Misc, _) | ImplSource::Param(ty::BoundConstness::ConstIfConst, _)
|
|
||||||
) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ocx = ObligationCtxt::new(&infcx);
|
|
||||||
ocx.register_obligations(impl_src.nested_obligations());
|
|
||||||
ocx.select_all_or_error().is_empty()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,4 +99,5 @@ impl const Drop for D {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lint this, since it can be dropped in const contexts
|
// Lint this, since it can be dropped in const contexts
|
||||||
|
// FIXME(effects)
|
||||||
fn d(this: D) {}
|
fn d(this: D) {}
|
||||||
|
|
|
@ -89,11 +89,5 @@ LL | | 46
|
||||||
LL | | }
|
LL | | }
|
||||||
| |_^
|
| |_^
|
||||||
|
|
||||||
error: this could be a `const fn`
|
error: aborting due to 11 previous errors
|
||||||
--> $DIR/could_be_const.rs:102:1
|
|
||||||
|
|
|
||||||
LL | fn d(this: D) {}
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 12 previous errors
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
struct X<const N: usize = {
|
struct X<const N: usize = {
|
||||||
(||1usize)()
|
(||1usize)()
|
||||||
//~^ ERROR cannot call non-const closure
|
//~^ ERROR cannot call non-const closure
|
||||||
//~| ERROR the trait bound
|
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
error[E0277]: the trait bound `[closure@$DIR/issue-93647.rs:2:6: 2:8]: Fn<()>` is not satisfied
|
|
||||||
--> $DIR/issue-93647.rs:2:5
|
|
||||||
|
|
|
||||||
LL | (||1usize)()
|
|
||||||
| ^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-93647.rs:2:6: 2:8]`
|
|
||||||
|
|
|
||||||
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-93647.rs:2:6: 2:8]`
|
|
||||||
note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-93647.rs:2:6: 2:8]`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-93647.rs:2:5
|
|
||||||
|
|
|
||||||
LL | (||1usize)()
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
= note: wrap the `[closure@$DIR/issue-93647.rs:2:6: 2:8]` in a closure with no arguments: `|| { /* code */ }`
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constants
|
error[E0015]: cannot call non-const closure in constants
|
||||||
--> $DIR/issue-93647.rs:2:5
|
--> $DIR/issue-93647.rs:2:5
|
||||||
|
|
|
|
||||||
|
@ -22,7 +8,6 @@ LL | (||1usize)()
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// known-bug: #103507
|
||||||
|
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
#![feature(const_trait_impl, inline_const, negative_impls)]
|
#![feature(const_trait_impl, inline_const, negative_impls)]
|
||||||
|
|
||||||
|
@ -14,6 +16,6 @@ impl Drop for UnconstDrop {
|
||||||
fn main() {
|
fn main() {
|
||||||
const {
|
const {
|
||||||
f(UnconstDrop);
|
f(UnconstDrop);
|
||||||
//~^ ERROR can't drop
|
//FIXME ~^ ERROR can't drop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,11 @@
|
||||||
error[E0277]: can't drop `UnconstDrop` in const contexts
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-block-const-bound.rs:16:9
|
--> $DIR/const-block-const-bound.rs:8:32
|
||||||
|
|
|
|
||||||
LL | f(UnconstDrop);
|
LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||||
| ^^^^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `UnconstDrop`
|
| ^ - value is dropped here
|
||||||
|
|
| |
|
||||||
= note: the trait bound `UnconstDrop: ~const Destruct` is not satisfied
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
help: consider borrowing here
|
|
||||||
|
|
|
||||||
LL | &f(UnconstDrop);
|
|
||||||
| +
|
|
||||||
LL | &mut f(UnconstDrop);
|
|
||||||
| ++++
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -1,16 +1,3 @@
|
||||||
error[E0277]: can't compare `TypeId` with `TypeId` in const contexts
|
|
||||||
--> $DIR/const_cmp_type_id.rs:8:13
|
|
||||||
|
|
|
||||||
LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId`
|
|
||||||
|
|
|
||||||
= help: the trait `~const PartialEq` is not implemented for `TypeId`
|
|
||||||
note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const`
|
|
||||||
--> $DIR/const_cmp_type_id.rs:8:13
|
|
||||||
|
|
|
||||||
LL | assert!(TypeId::of::<u8>() == TypeId::of::<u8>());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
error[E0015]: cannot call non-const operator in constant functions
|
||||||
--> $DIR/const_cmp_type_id.rs:8:13
|
--> $DIR/const_cmp_type_id.rs:8:13
|
||||||
|
|
|
|
||||||
|
@ -21,19 +8,6 @@ note: impl defined here, but it is not `const`
|
||||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error[E0277]: can't compare `TypeId` with `TypeId` in const contexts
|
|
||||||
--> $DIR/const_cmp_type_id.rs:9:13
|
|
||||||
|
|
|
||||||
LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId`
|
|
||||||
|
|
|
||||||
= help: the trait `~const PartialEq` is not implemented for `TypeId`
|
|
||||||
note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const`
|
|
||||||
--> $DIR/const_cmp_type_id.rs:9:13
|
|
||||||
|
|
|
||||||
LL | assert!(TypeId::of::<()>() != TypeId::of::<u8>());
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
error[E0015]: cannot call non-const operator in constant functions
|
||||||
--> $DIR/const_cmp_type_id.rs:9:13
|
--> $DIR/const_cmp_type_id.rs:9:13
|
||||||
|
|
|
|
||||||
|
@ -44,19 +18,6 @@ note: impl defined here, but it is not `const`
|
||||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error[E0277]: can't compare `TypeId` with `TypeId` in const contexts
|
|
||||||
--> $DIR/const_cmp_type_id.rs:10:22
|
|
||||||
|
|
|
||||||
LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>();
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId < TypeId` and `TypeId > TypeId`
|
|
||||||
|
|
|
||||||
= help: the trait `~const PartialOrd` is not implemented for `TypeId`
|
|
||||||
note: the trait `PartialOrd` is implemented for `TypeId`, but that implementation is not `const`
|
|
||||||
--> $DIR/const_cmp_type_id.rs:10:22
|
|
||||||
|
|
|
||||||
LL | const _A: bool = TypeId::of::<u8>() < TypeId::of::<u16>();
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constants
|
error[E0015]: cannot call non-const operator in constants
|
||||||
--> $DIR/const_cmp_type_id.rs:10:22
|
--> $DIR/const_cmp_type_id.rs:10:22
|
||||||
|
|
|
|
||||||
|
@ -68,7 +29,6 @@ note: impl defined here, but it is not `const`
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `PartialOrd` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -5,6 +5,5 @@ fn main() {
|
||||||
match () {
|
match () {
|
||||||
const { (|| {})() } => {}
|
const { (|| {})() } => {}
|
||||||
//~^ ERROR cannot call non-const closure in constants
|
//~^ ERROR cannot call non-const closure in constants
|
||||||
//~| ERROR the trait bound
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
error[E0277]: the trait bound `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]: Fn<()>` is not satisfied
|
|
||||||
--> $DIR/invalid-inline-const-in-match-arm.rs:6:17
|
|
||||||
|
|
|
||||||
LL | const { (|| {})() } => {}
|
|
||||||
| ^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]`
|
|
||||||
|
|
|
||||||
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]`
|
|
||||||
note: the trait `Fn<()>` is implemented for `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]`, but that implementation is not `const`
|
|
||||||
--> $DIR/invalid-inline-const-in-match-arm.rs:6:17
|
|
||||||
|
|
|
||||||
LL | const { (|| {})() } => {}
|
|
||||||
| ^^^^^^^^^
|
|
||||||
= note: wrap the `[closure@$DIR/invalid-inline-const-in-match-arm.rs:6:18: 6:20]` in a closure with no arguments: `|| { /* code */ }`
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constants
|
error[E0015]: cannot call non-const closure in constants
|
||||||
--> $DIR/invalid-inline-const-in-match-arm.rs:6:17
|
--> $DIR/invalid-inline-const-in-match-arm.rs:6:17
|
||||||
|
|
|
|
||||||
|
@ -22,7 +8,6 @@ LL | const { (|| {})() } => {}
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
const X: u8 =
|
const X: u8 =
|
||||||
|| -> u8 { 5 }()
|
|| -> u8 { 5 }()
|
||||||
//~^ ERROR cannot call non-const closure
|
//~^ ERROR cannot call non-const closure
|
||||||
//~| ERROR the trait bound
|
|
||||||
;
|
;
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
error[E0277]: the trait bound `[closure@$DIR/issue-28113.rs:4:5: 4:13]: Fn<()>` is not satisfied
|
|
||||||
--> $DIR/issue-28113.rs:4:5
|
|
||||||
|
|
|
||||||
LL | || -> u8 { 5 }()
|
|
||||||
| ^^^^^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-28113.rs:4:5: 4:13]`
|
|
||||||
|
|
|
||||||
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-28113.rs:4:5: 4:13]`
|
|
||||||
note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-28113.rs:4:5: 4:13]`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-28113.rs:4:5
|
|
||||||
|
|
|
||||||
LL | || -> u8 { 5 }()
|
|
||||||
| ^^^^^^^^^^^^^^^^
|
|
||||||
= note: wrap the `[closure@$DIR/issue-28113.rs:4:5: 4:13]` in a closure with no arguments: `|| { /* code */ }`
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constants
|
error[E0015]: cannot call non-const closure in constants
|
||||||
--> $DIR/issue-28113.rs:4:5
|
--> $DIR/issue-28113.rs:4:5
|
||||||
|
|
|
|
||||||
|
@ -22,7 +8,6 @@ LL | || -> u8 { 5 }()
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const fn foo() { (||{})() }
|
const fn foo() { (||{})() }
|
||||||
//~^ ERROR cannot call non-const closure
|
//~^ ERROR cannot call non-const closure
|
||||||
//~| ERROR the trait bound
|
|
||||||
|
|
||||||
const fn bad(input: fn()) {
|
const fn bad(input: fn()) {
|
||||||
input()
|
input()
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
error[E0277]: the trait bound `[closure@$DIR/issue-56164.rs:1:19: 1:21]: Fn<()>` is not satisfied
|
|
||||||
--> $DIR/issue-56164.rs:1:18
|
|
||||||
|
|
|
||||||
LL | const fn foo() { (||{})() }
|
|
||||||
| ^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-56164.rs:1:19: 1:21]`
|
|
||||||
|
|
|
||||||
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-56164.rs:1:19: 1:21]`
|
|
||||||
note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-56164.rs:1:19: 1:21]`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-56164.rs:1:18
|
|
||||||
|
|
|
||||||
LL | const fn foo() { (||{})() }
|
|
||||||
| ^^^^^^^^
|
|
||||||
= note: wrap the `[closure@$DIR/issue-56164.rs:1:19: 1:21]` in a closure with no arguments: `|| { /* code */ }`
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error[E0015]: cannot call non-const closure in constant functions
|
||||||
--> $DIR/issue-56164.rs:1:18
|
--> $DIR/issue-56164.rs:1:18
|
||||||
|
|
|
|
||||||
|
@ -23,12 +9,11 @@ LL | const fn foo() { (||{})() }
|
||||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: function pointer calls are not allowed in constant functions
|
error: function pointer calls are not allowed in constant functions
|
||||||
--> $DIR/issue-56164.rs:6:5
|
--> $DIR/issue-56164.rs:5:5
|
||||||
|
|
|
|
||||||
LL | input()
|
LL | input()
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
struct Bug {
|
struct Bug {
|
||||||
a: [(); (|| { 0 })()] //~ ERROR cannot call non-const closure
|
a: [(); (|| { 0 })()] //~ ERROR cannot call non-const closure
|
||||||
//~^ ERROR the trait bound
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,17 +1,3 @@
|
||||||
error[E0277]: the trait bound `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]: Fn<()>` is not satisfied
|
|
||||||
--> $DIR/issue-68542-closure-in-array-len.rs:6:13
|
|
||||||
|
|
|
||||||
LL | a: [(); (|| { 0 })()]
|
|
||||||
| ^^^^^^^^^^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]`
|
|
||||||
|
|
|
||||||
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]`
|
|
||||||
note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-68542-closure-in-array-len.rs:6:13
|
|
||||||
|
|
|
||||||
LL | a: [(); (|| { 0 })()]
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
= note: wrap the `[closure@$DIR/issue-68542-closure-in-array-len.rs:6:14: 6:16]` in a closure with no arguments: `|| { /* code */ }`
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constants
|
error[E0015]: cannot call non-const closure in constants
|
||||||
--> $DIR/issue-68542-closure-in-array-len.rs:6:13
|
--> $DIR/issue-68542-closure-in-array-len.rs:6:13
|
||||||
|
|
|
|
||||||
|
@ -22,7 +8,6 @@ LL | a: [(); (|| { 0 })()]
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,16 +1,3 @@
|
||||||
error[E0277]: can't compare `TypeId` with `TypeId` in const contexts
|
|
||||||
--> $DIR/issue-73976-monomorphic.rs:21:5
|
|
||||||
|
|
|
||||||
LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no implementation for `TypeId == TypeId`
|
|
||||||
|
|
|
||||||
= help: the trait `~const PartialEq` is not implemented for `TypeId`
|
|
||||||
note: the trait `PartialEq` is implemented for `TypeId`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-73976-monomorphic.rs:21:5
|
|
||||||
|
|
|
||||||
LL | GetTypeId::<T>::VALUE == GetTypeId::<usize>::VALUE
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
error[E0015]: cannot call non-const operator in constant functions
|
||||||
--> $DIR/issue-73976-monomorphic.rs:21:5
|
--> $DIR/issue-73976-monomorphic.rs:21:5
|
||||||
|
|
|
|
||||||
|
@ -21,7 +8,6 @@ note: impl defined here, but it is not `const`
|
||||||
--> $SRC_DIR/core/src/any.rs:LL:COL
|
--> $SRC_DIR/core/src/any.rs:LL:COL
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// known-bug: #103507
|
||||||
|
|
||||||
#![feature(const_trait_impl, const_mut_refs)]
|
#![feature(const_trait_impl, const_mut_refs)]
|
||||||
|
|
||||||
struct Foo<'a> {
|
struct Foo<'a> {
|
||||||
|
@ -7,9 +9,9 @@ struct Foo<'a> {
|
||||||
impl<'a> Foo<'a> {
|
impl<'a> Foo<'a> {
|
||||||
const fn spam(&mut self, baz: &mut Vec<u32>) {
|
const fn spam(&mut self, baz: &mut Vec<u32>) {
|
||||||
self.bar[0] = baz.len();
|
self.bar[0] = baz.len();
|
||||||
//~^ ERROR: cannot call
|
//FIXME ~^ ERROR: cannot call
|
||||||
//~| ERROR: cannot call
|
//FIXME ~| ERROR: cannot call
|
||||||
//~| ERROR: the trait bound
|
//FIXME ~| ERROR: the trait bound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,13 @@
|
||||||
error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions
|
error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions
|
||||||
--> $DIR/issue-94675.rs:9:27
|
--> $DIR/issue-94675.rs:11:27
|
||||||
|
|
|
|
||||||
LL | self.bar[0] = baz.len();
|
LL | self.bar[0] = baz.len();
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
|
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error[E0277]: the trait bound `Vec<usize>: ~const IndexMut<usize>` is not satisfied
|
|
||||||
--> $DIR/issue-94675.rs:9:9
|
|
||||||
|
|
|
||||||
LL | self.bar[0] = baz.len();
|
|
||||||
| ^^^^^^^^^^^ vector indices are of type `usize` or ranges of `usize`
|
|
||||||
|
|
|
||||||
= help: the trait `~const IndexMut<usize>` is not implemented for `Vec<usize>`
|
|
||||||
note: the trait `IndexMut<usize>` is implemented for `Vec<usize>`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-94675.rs:9:9
|
|
||||||
|
|
|
||||||
LL | self.bar[0] = baz.len();
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
error[E0015]: cannot call non-const operator in constant functions
|
||||||
--> $DIR/issue-94675.rs:9:9
|
--> $DIR/issue-94675.rs:11:9
|
||||||
|
|
|
|
||||||
LL | self.bar[0] = baz.len();
|
LL | self.bar[0] = baz.len();
|
||||||
| ^^^^^^^^^^^
|
| ^^^^^^^^^^^
|
||||||
|
@ -29,7 +16,6 @@ note: impl defined here, but it is not `const`
|
||||||
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
--> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
// Regression test for issue #89938.
|
// Regression test for issue #89938.
|
||||||
// check-pass
|
|
||||||
// compile-flags: --crate-type=lib
|
// compile-flags: --crate-type=lib
|
||||||
|
// known-bug: #103507
|
||||||
|
// failure-status: 101
|
||||||
|
// normalize-stderr-test "note: .*\n\n" -> ""
|
||||||
|
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
|
||||||
|
// normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
||||||
|
// rustc-env:RUST_BACKTRACE=0
|
||||||
|
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
|
|
||||||
pub const fn f() {
|
pub const fn f() {
|
||||||
|
|
6
tests/ui/consts/precise-drop-with-promoted.stderr
Normal file
6
tests/ui/consts/precise-drop-with-promoted.stderr
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
||||||
|
query stack during panic:
|
||||||
|
#0 [mir_drops_elaborated_and_const_checked] elaborating drops for `f`
|
||||||
|
#1 [analysis] running analysis passes on this crate
|
||||||
|
end of query stack
|
|
@ -1,3 +1,5 @@
|
||||||
|
// known-bug: #103507
|
||||||
|
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
@ -7,15 +9,15 @@ impl const Drop for Panic { fn drop(&mut self) { panic!(); } }
|
||||||
pub const fn id<T>(x: T) -> T { x }
|
pub const fn id<T>(x: T) -> T { x }
|
||||||
pub const C: () = {
|
pub const C: () = {
|
||||||
let _: &'static _ = &id(&Panic);
|
let _: &'static _ = &id(&Panic);
|
||||||
//~^ ERROR: temporary value dropped while borrowed
|
//FIXME ~^ ERROR: temporary value dropped while borrowed
|
||||||
//~| ERROR: temporary value dropped while borrowed
|
//FIXME ~| ERROR: temporary value dropped while borrowed
|
||||||
};
|
};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let _: &'static _ = &id(&Panic);
|
let _: &'static _ = &id(&Panic);
|
||||||
//~^ ERROR: temporary value dropped while borrowed
|
//FIXME ~^ ERROR: temporary value dropped while borrowed
|
||||||
//~| ERROR: temporary value dropped while borrowed
|
//FIXME ~| ERROR: temporary value dropped while borrowed
|
||||||
let _: &'static _ = &&(Panic, 0).1;
|
let _: &'static _ = &&(Panic, 0).1;
|
||||||
//~^ ERROR: temporary value dropped while borrowed
|
//FIXME~^ ERROR: temporary value dropped while borrowed
|
||||||
//~| ERROR: temporary value dropped while borrowed
|
//FIXME~| ERROR: temporary value dropped while borrowed
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
|
error[E0493]: destructor of `Panic` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/promoted_const_call.rs:11:30
|
||||||
|
|
|
||||||
|
LL | let _: &'static _ = &id(&Panic);
|
||||||
|
| ^^^^^ - value is dropped here
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constants
|
||||||
|
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/promoted_const_call.rs:9:26
|
--> $DIR/promoted_const_call.rs:11:26
|
||||||
|
|
|
|
||||||
LL | let _: &'static _ = &id(&Panic);
|
LL | let _: &'static _ = &id(&Panic);
|
||||||
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||||
|
@ -10,7 +18,7 @@ LL | };
|
||||||
| - temporary value is freed at the end of this statement
|
| - temporary value is freed at the end of this statement
|
||||||
|
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/promoted_const_call.rs:9:30
|
--> $DIR/promoted_const_call.rs:11:30
|
||||||
|
|
|
|
||||||
LL | let _: &'static _ = &id(&Panic);
|
LL | let _: &'static _ = &id(&Panic);
|
||||||
| ---------- ^^^^^ - temporary value is freed at the end of this statement
|
| ---------- ^^^^^ - temporary value is freed at the end of this statement
|
||||||
|
@ -19,7 +27,7 @@ LL | let _: &'static _ = &id(&Panic);
|
||||||
| type annotation requires that borrow lasts for `'static`
|
| type annotation requires that borrow lasts for `'static`
|
||||||
|
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/promoted_const_call.rs:15:26
|
--> $DIR/promoted_const_call.rs:17:26
|
||||||
|
|
|
|
||||||
LL | let _: &'static _ = &id(&Panic);
|
LL | let _: &'static _ = &id(&Panic);
|
||||||
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||||
|
@ -30,7 +38,7 @@ LL | }
|
||||||
| - temporary value is freed at the end of this statement
|
| - temporary value is freed at the end of this statement
|
||||||
|
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/promoted_const_call.rs:15:30
|
--> $DIR/promoted_const_call.rs:17:30
|
||||||
|
|
|
|
||||||
LL | let _: &'static _ = &id(&Panic);
|
LL | let _: &'static _ = &id(&Panic);
|
||||||
| ---------- ^^^^^ - temporary value is freed at the end of this statement
|
| ---------- ^^^^^ - temporary value is freed at the end of this statement
|
||||||
|
@ -39,7 +47,7 @@ LL | let _: &'static _ = &id(&Panic);
|
||||||
| type annotation requires that borrow lasts for `'static`
|
| type annotation requires that borrow lasts for `'static`
|
||||||
|
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/promoted_const_call.rs:18:26
|
--> $DIR/promoted_const_call.rs:20:26
|
||||||
|
|
|
|
||||||
LL | let _: &'static _ = &&(Panic, 0).1;
|
LL | let _: &'static _ = &&(Panic, 0).1;
|
||||||
| ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
|
| ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||||
|
@ -50,7 +58,7 @@ LL | }
|
||||||
| - temporary value is freed at the end of this statement
|
| - temporary value is freed at the end of this statement
|
||||||
|
|
||||||
error[E0716]: temporary value dropped while borrowed
|
error[E0716]: temporary value dropped while borrowed
|
||||||
--> $DIR/promoted_const_call.rs:18:27
|
--> $DIR/promoted_const_call.rs:20:27
|
||||||
|
|
|
|
||||||
LL | let _: &'static _ = &&(Panic, 0).1;
|
LL | let _: &'static _ = &&(Panic, 0).1;
|
||||||
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||||
|
@ -60,6 +68,7 @@ LL | let _: &'static _ = &&(Panic, 0).1;
|
||||||
LL | }
|
LL | }
|
||||||
| - temporary value is freed at the end of this statement
|
| - temporary value is freed at the end of this statement
|
||||||
|
|
||||||
error: aborting due to 6 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0716`.
|
Some errors have detailed explanations: E0493, E0716.
|
||||||
|
For more information about an error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
// known-bug: #103507
|
// known-bug: #103507
|
||||||
// failure-status: 101
|
|
||||||
// normalize-stderr-test "note: .*\n\n" -> ""
|
|
||||||
// normalize-stderr-test "thread 'rustc' panicked.*\n" -> ""
|
|
||||||
// normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
|
|
||||||
// rustc-env:RUST_BACKTRACE=0
|
|
||||||
|
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
error: internal compiler error: compiler/rustc_middle/src/ty/normalize_erasing_regions.rs:LL:CC: Failed to normalize <for<'a, 'b> fn(&'a Alias<'b>) {foo} as std::ops::FnOnce<(&&S,)>>::Output, maybe try to call `try_normalize_erasing_regions` instead
|
error[E0493]: destructor of `F` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/normalize-tait-in-const.rs:25:79
|
||||||
|
|
|
||||||
|
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||||
|
| ^^^ the destructor for this type cannot be evaluated in constant functions
|
||||||
|
LL | fun(filter_positive());
|
||||||
|
LL | }
|
||||||
|
| - value is dropped here
|
||||||
|
|
||||||
query stack during panic:
|
|
||||||
#0 [eval_to_allocation_raw] const-evaluating + checking `BAR`
|
|
||||||
#1 [eval_to_const_value_raw] simplifying constant for the type system `BAR`
|
|
||||||
end of query stack
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -23,7 +23,7 @@ pub const fn add_i32(a: i32, b: i32) -> i32 {
|
||||||
|
|
||||||
pub const fn add_u32(a: u32, b: u32) -> u32 {
|
pub const fn add_u32(a: u32, b: u32) -> u32 {
|
||||||
a.plus(b)
|
a.plus(b)
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR cannot call
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
|
error[E0015]: cannot call non-const fn `<u32 as Plus>::plus` in constant functions
|
||||||
--> $DIR/call-const-trait-method-fail.rs:25:7
|
--> $DIR/call-const-trait-method-fail.rs:25:7
|
||||||
|
|
|
|
||||||
LL | a.plus(b)
|
LL | a.plus(b)
|
||||||
| ^^^^ the trait `~const Plus` is not implemented for `u32`
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
note: the trait `Plus` is implemented for `u32`, but that implementation is not `const`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/call-const-trait-method-fail.rs:25:7
|
|
||||||
|
|
|
||||||
LL | a.plus(b)
|
|
||||||
| ^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,15 +1,3 @@
|
||||||
error[E0277]: can't compare `T` with `T` in const contexts
|
|
||||||
--> $DIR/call-generic-method-fail.rs:5:5
|
|
||||||
|
|
|
||||||
LL | *t == *t
|
|
||||||
| ^^^^^^^^ no implementation for `T == T`
|
|
||||||
|
|
|
||||||
note: the trait `PartialEq` is implemented for `T`, but that implementation is not `const`
|
|
||||||
--> $DIR/call-generic-method-fail.rs:5:5
|
|
||||||
|
|
|
||||||
LL | *t == *t
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
error[E0015]: cannot call non-const operator in constant functions
|
||||||
--> $DIR/call-generic-method-fail.rs:5:5
|
--> $DIR/call-generic-method-fail.rs:5:5
|
||||||
|
|
|
|
||||||
|
@ -22,7 +10,6 @@ help: consider further restricting this bound
|
||||||
LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool {
|
LL | pub const fn equals_self<T: PartialEq + ~const std::cmp::PartialEq>(t: &T) -> bool {
|
||||||
| ++++++++++++++++++++++++++++
|
| ++++++++++++++++++++++++++++
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// check-pass
|
||||||
|
// known-bug: #110395
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
struct S;
|
struct S;
|
||||||
|
@ -21,6 +24,6 @@ const fn equals_self<T: ~const Foo>(t: &T) -> bool {
|
||||||
// it not using the impl.
|
// it not using the impl.
|
||||||
|
|
||||||
pub const EQ: bool = equals_self(&S);
|
pub const EQ: bool = equals_self(&S);
|
||||||
//~^ ERROR
|
// FIXME(effects) ~^ ERROR
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
|
|
||||||
--> $DIR/call-generic-method-nonconst.rs:23:22
|
|
||||||
|
|
|
||||||
LL | pub const EQ: bool = equals_self(&S);
|
|
||||||
| ^^^^^^^^^^^^^^^ the trait `~const Foo` is not implemented for `S`
|
|
||||||
|
|
|
||||||
note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
|
|
||||||
--> $DIR/call-generic-method-nonconst.rs:23:22
|
|
||||||
|
|
|
||||||
LL | pub const EQ: bool = equals_self(&S);
|
|
||||||
| ^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,16 +1,21 @@
|
||||||
error[E0277]: the trait bound `(): ~const Tr` is not satisfied in `fn(()) -> i32 {<() as Tr>::a}`
|
error[E0080]: evaluation of constant value failed
|
||||||
--> $DIR/const-closure-trait-method-fail.rs:18:23
|
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||||
|
|
|
|
||||||
LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
|
= note: calling non-const function `<() as Tr>::a`
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ within `fn(()) -> i32 {<() as Tr>::a}`, the trait `~const Tr` is not implemented for `()`
|
|
||||||
|
|
|
|
||||||
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
|
note: inside `<fn(()) -> i32 {<() as Tr>::a} as FnOnce<((),)>>::call_once - shim(fn(()) -> i32 {<() as Tr>::a})`
|
||||||
|
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||||
|
note: inside `need_const_closure::<fn(()) -> i32 {<() as Tr>::a}>`
|
||||||
|
--> $DIR/const-closure-trait-method-fail.rs:15:5
|
||||||
|
|
|
||||||
|
LL | x(())
|
||||||
|
| ^^^^^
|
||||||
|
note: inside `_`
|
||||||
--> $DIR/const-closure-trait-method-fail.rs:18:23
|
--> $DIR/const-closure-trait-method-fail.rs:18:23
|
||||||
|
|
|
|
||||||
LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
|
LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
= note: required because it appears within the type `fn(()) -> i32 {<() as Tr>::a}`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -22,7 +22,7 @@ impl const ConstDefaultFn for ConstImpl {
|
||||||
|
|
||||||
const fn test() {
|
const fn test() {
|
||||||
NonConstImpl.a();
|
NonConstImpl.a();
|
||||||
//~^ ERROR the trait bound
|
//~^ ERROR cannot call
|
||||||
ConstImpl.a();
|
ConstImpl.a();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
|
error[E0015]: cannot call non-const fn `<NonConstImpl as ConstDefaultFn>::a` in constant functions
|
||||||
--> $DIR/const-default-method-bodies.rs:24:18
|
--> $DIR/const-default-method-bodies.rs:24:18
|
||||||
|
|
|
|
||||||
LL | NonConstImpl.a();
|
LL | NonConstImpl.a();
|
||||||
| ^ the trait `~const ConstDefaultFn` is not implemented for `NonConstImpl`
|
| ^^^
|
||||||
|
|
|
|
||||||
note: the trait `ConstDefaultFn` is implemented for `NonConstImpl`, but that implementation is not `const`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/const-default-method-bodies.rs:24:5
|
|
||||||
|
|
|
||||||
LL | NonConstImpl.a();
|
|
||||||
| ^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// check-pass
|
// known-bug: #110395
|
||||||
|
// FIXME check-pass
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![feature(const_precise_live_drops)]
|
#![feature(const_precise_live_drops)]
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
error[E0493]: destructor of `E` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/const-drop-bound.rs:12:13
|
||||||
|
|
|
||||||
|
LL | Err(_e) => None,
|
||||||
|
| ^^ the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0493`.
|
|
@ -1,50 +1,11 @@
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-drop-fail-2.rs:31:23
|
--> $DIR/const-drop-fail-2.rs:29:36
|
||||||
|
|
|
|
||||||
LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
|
| ^ - value is dropped here
|
||||||
|
|
| |
|
||||||
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
--> $DIR/const-drop-fail-2.rs:31:23
|
|
||||||
|
|
|
||||||
LL | const _: () = check::<ConstDropImplWithBounds<NonTrivialDrop>>(
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: required by a bound in `ConstDropImplWithBounds`
|
|
||||||
--> $DIR/const-drop-fail-2.rs:21:35
|
|
||||||
|
|
|
||||||
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
|
|
||||||
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `NonTrivialDrop: ~const A` is not satisfied
|
error: aborting due to previous error
|
||||||
--> $DIR/const-drop-fail-2.rs:32:5
|
|
||||||
|
|
|
||||||
LL | ConstDropImplWithBounds(PhantomData)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `~const A` is not implemented for `NonTrivialDrop`
|
|
||||||
|
|
|
||||||
note: the trait `A` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
|
||||||
--> $DIR/const-drop-fail-2.rs:32:5
|
|
||||||
|
|
|
||||||
LL | ConstDropImplWithBounds(PhantomData)
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
note: required by a bound in `ConstDropImplWithBounds`
|
|
||||||
--> $DIR/const-drop-fail-2.rs:21:35
|
|
||||||
|
|
|
||||||
LL | struct ConstDropImplWithBounds<T: ~const A>(PhantomData<T>);
|
|
||||||
| ^^^^^^^^ required by this bound in `ConstDropImplWithBounds`
|
|
||||||
|
|
||||||
error[E0367]: `Drop` impl requires `T: ~const A` but the struct it is implemented for does not
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
--> $DIR/const-drop-fail-2.rs:37:9
|
|
||||||
|
|
|
||||||
LL | impl<T: ~const A> const Drop for ConstDropImplWithNonConstBounds<T> {
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
note: the implementor must specify the same requirement
|
|
||||||
--> $DIR/const-drop-fail-2.rs:35:1
|
|
||||||
|
|
|
||||||
LL | struct ConstDropImplWithNonConstBounds<T: A>(PhantomData<T>);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0277, E0367.
|
|
||||||
For more information about an error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -1,58 +1,9 @@
|
||||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
--> $DIR/const-drop-fail.rs:24:36
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
| ^ the destructor for this type cannot be evaluated in constant functions
|
||||||
...
|
|
||||||
LL | / check_all! {
|
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
|
|
|
||||||
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
|
||||||
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | / check_all! {
|
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
= note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
error: aborting due to previous error
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
|
||||||
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
|
||||||
...
|
|
||||||
LL | / check_all! {
|
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
|
|
|
||||||
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
|
||||||
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | / check_all! {
|
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
note: required because it appears within the type `ConstImplWithDropGlue`
|
|
||||||
--> $DIR/const-drop-fail.rs:18:8
|
|
||||||
|
|
|
||||||
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -1,58 +1,11 @@
|
||||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
--> $DIR/const-drop-fail.rs:24:36
|
||||||
|
|
|
|
||||||
LL | const _: () = check($exp);
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^ the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
| ^ - value is dropped here
|
||||||
...
|
| |
|
||||||
LL | / check_all! {
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
|
|
|
||||||
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
|
||||||
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | / check_all! {
|
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
= note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error[E0277]: can't drop `NonTrivialDrop` in const contexts
|
error: aborting due to previous error
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
|
||||||
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ^^^^^^^^^^^ within `ConstImplWithDropGlue`, the trait `~const Destruct` is not implemented for `NonTrivialDrop`
|
|
||||||
...
|
|
||||||
LL | / check_all! {
|
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
|
|
|
||||||
note: the trait `Destruct` is implemented for `NonTrivialDrop`, but that implementation is not `const`
|
|
||||||
--> $DIR/const-drop-fail.rs:28:23
|
|
||||||
|
|
|
||||||
LL | const _: () = check($exp);
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
...
|
|
||||||
LL | / check_all! {
|
|
||||||
LL | | NonTrivialDrop,
|
|
||||||
LL | | ConstImplWithDropGlue(NonTrivialDrop),
|
|
||||||
LL | | }
|
|
||||||
| |_- in this macro invocation
|
|
||||||
note: required because it appears within the type `ConstImplWithDropGlue`
|
|
||||||
--> $DIR/const-drop-fail.rs:18:8
|
|
||||||
|
|
|
||||||
LL | struct ConstImplWithDropGlue(NonTrivialDrop);
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
= note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/const-drop.rs:19:32
|
||||||
|
|
|
||||||
|
LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||||
|
| ^ - value is dropped here
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
|
error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/const-drop.rs:24:13
|
||||||
|
|
|
||||||
|
LL | let _ = S(&mut c);
|
||||||
|
| ^^^^^^^^^- value is dropped here
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0493`.
|
|
@ -1,9 +1,10 @@
|
||||||
// run-pass
|
// FIXME run-pass
|
||||||
|
// known-bug: #110395
|
||||||
// revisions: stock precise
|
// revisions: stock precise
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![feature(const_mut_refs)]
|
#![feature(const_mut_refs)]
|
||||||
#![feature(never_type)]
|
#![feature(never_type)]
|
||||||
#![cfg_attr(precise, feature(const_precise_live_drops))]
|
// #![cfg_attr(precise, feature(const_precise_live_drops))]
|
||||||
|
|
||||||
use std::marker::Destruct;
|
use std::marker::Destruct;
|
||||||
|
|
||||||
|
@ -16,10 +17,12 @@ impl<'a> const Drop for S<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn a<T: ~const Destruct>(_: T) {}
|
const fn a<T: ~const Destruct>(_: T) {}
|
||||||
|
//FIXME ~^ ERROR destructor of
|
||||||
|
|
||||||
const fn b() -> u8 {
|
const fn b() -> u8 {
|
||||||
let mut c = 0;
|
let mut c = 0;
|
||||||
let _ = S(&mut c);
|
let _ = S(&mut c);
|
||||||
|
//FIXME ~^ ERROR destructor of
|
||||||
a(S(&mut c));
|
a(S(&mut c));
|
||||||
c
|
c
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/const-drop.rs:19:32
|
||||||
|
|
|
||||||
|
LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||||
|
| ^ - value is dropped here
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
|
error[E0493]: destructor of `S<'_>` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/const-drop.rs:24:13
|
||||||
|
|
|
||||||
|
LL | let _ = S(&mut c);
|
||||||
|
| ^^^^^^^^^- value is dropped here
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0493`.
|
|
@ -1,15 +1,11 @@
|
||||||
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
|
error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
|
||||||
--> $DIR/cross-crate.rs:17:14
|
--> $DIR/cross-crate.rs:17:14
|
||||||
|
|
|
|
||||||
LL | NonConst.func();
|
LL | NonConst.func();
|
||||||
| ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/cross-crate.rs:17:5
|
|
||||||
|
|
|
||||||
LL | NonConst.func();
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -15,10 +15,11 @@ fn non_const_context() {
|
||||||
const fn const_context() {
|
const fn const_context() {
|
||||||
#[cfg(any(stocknc, gatednc))]
|
#[cfg(any(stocknc, gatednc))]
|
||||||
NonConst.func();
|
NonConst.func();
|
||||||
//[stocknc]~^ ERROR: the trait bound
|
//[stocknc]~^ ERROR: cannot call
|
||||||
//[gatednc]~^^ ERROR: the trait bound
|
//[gatednc]~^^ ERROR: cannot call
|
||||||
Const.func();
|
Const.func();
|
||||||
//[stock]~^ ERROR: cannot call
|
//[stock]~^ ERROR: cannot call
|
||||||
|
//[stocknc]~^^ ERROR: cannot call
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
error[E0277]: the trait bound `cross_crate::NonConst: cross_crate::MyTrait` is not satisfied
|
error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
|
||||||
--> $DIR/cross-crate.rs:17:14
|
--> $DIR/cross-crate.rs:17:14
|
||||||
|
|
|
|
||||||
LL | NonConst.func();
|
LL | NonConst.func();
|
||||||
| ^^^^ the trait `~const cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
| ^^^^^^
|
||||||
|
|
|
|
||||||
note: the trait `cross_crate::MyTrait` is implemented for `cross_crate::NonConst`, but that implementation is not `const`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/cross-crate.rs:17:5
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
|
error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
|
||||||
|
--> $DIR/cross-crate.rs:20:11
|
||||||
|
|
|
|
||||||
LL | NonConst.func();
|
LL | Const.func();
|
||||||
| ^^^^^^^^
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
= help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// known-bug: #110395
|
||||||
|
// check-pass
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
|
@ -10,7 +13,7 @@ const fn foo<T>() where T: ~const Tr {}
|
||||||
pub trait Foo {
|
pub trait Foo {
|
||||||
fn foo() {
|
fn foo() {
|
||||||
foo::<()>();
|
foo::<()>();
|
||||||
//~^ ERROR the trait bound `(): ~const Tr` is not satisfied
|
//FIXME ~^ ERROR the trait bound `(): ~const Tr` is not satisfied
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
|
||||||
--> $DIR/default-method-body-is-const-body-checking.rs:12:9
|
|
||||||
|
|
|
||||||
LL | foo::<()>();
|
|
||||||
| ^^^^^^^^^^^ the trait `~const Tr` is not implemented for `()`
|
|
||||||
|
|
|
||||||
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
|
|
||||||
--> $DIR/default-method-body-is-const-body-checking.rs:12:9
|
|
||||||
|
|
|
||||||
LL | foo::<()>();
|
|
||||||
| ^^^^^^^^^^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// known-bug: #110395
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
|
@ -6,7 +7,7 @@ pub trait Tr {
|
||||||
|
|
||||||
fn b(&self) {
|
fn b(&self) {
|
||||||
().a()
|
().a()
|
||||||
//~^ ERROR the trait bound
|
//FIXME ~^ ERROR the trait bound
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,11 @@
|
||||||
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
error[E0015]: cannot call non-const fn `<() as Tr>::a` in constant functions
|
||||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
--> $DIR/default-method-body-is-const-same-trait-ck.rs:9:12
|
||||||
|
|
|
|
||||||
LL | ().a()
|
LL | ().a()
|
||||||
| ^ the trait `~const Tr` is not implemented for `()`
|
| ^^^
|
||||||
|
|
|
|
||||||
note: the trait `Tr` is implemented for `()`, but that implementation is not `const`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:9
|
|
||||||
|
|
|
||||||
LL | ().a()
|
|
||||||
| ^^
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
|
// known-bug: #110395
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
struct Bug {
|
struct Bug {
|
||||||
inner: [(); match || 1 {
|
inner: [(); match || 1 {
|
||||||
n => n(),
|
n => n(),
|
||||||
//~^ ERROR the trait bound
|
//FIXME ~^ ERROR the trait bound
|
||||||
//~| ERROR the trait bound
|
//FIXME ~| ERROR the trait bound
|
||||||
//~| ERROR cannot call non-const closure in constants
|
//FIXME ~| ERROR cannot call non-const closure in constants
|
||||||
}],
|
}],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,41 +1,11 @@
|
||||||
error[E0277]: the trait bound `[closure@$DIR/issue-102985.rs:4:23: 4:25]: ~const Fn<()>` is not satisfied
|
|
||||||
--> $DIR/issue-102985.rs:5:14
|
|
||||||
|
|
|
||||||
LL | n => n(),
|
|
||||||
| ^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
|
|
||||||
|
|
|
||||||
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
|
|
||||||
note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-102985.rs:4:23: 4:25]`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-102985.rs:5:14
|
|
||||||
|
|
|
||||||
LL | n => n(),
|
|
||||||
| ^^^
|
|
||||||
= note: wrap the `[closure@$DIR/issue-102985.rs:4:23: 4:25]` in a closure with no arguments: `|| { /* code */ }`
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `[closure@$DIR/issue-102985.rs:4:23: 4:25]: ~const Fn<()>` is not satisfied
|
|
||||||
--> $DIR/issue-102985.rs:5:14
|
|
||||||
|
|
|
||||||
LL | n => n(),
|
|
||||||
| ^^^ expected an `Fn<()>` closure, found `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
|
|
||||||
|
|
|
||||||
= help: the trait `~const Fn<()>` is not implemented for closure `[closure@$DIR/issue-102985.rs:4:23: 4:25]`
|
|
||||||
note: the trait `Fn<()>` is implemented for `[closure@$DIR/issue-102985.rs:4:23: 4:25]`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-102985.rs:5:14
|
|
||||||
|
|
|
||||||
LL | n => n(),
|
|
||||||
| ^^^
|
|
||||||
= note: wrap the `[closure@$DIR/issue-102985.rs:4:23: 4:25]` in a closure with no arguments: `|| { /* code */ }`
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constants
|
error[E0015]: cannot call non-const closure in constants
|
||||||
--> $DIR/issue-102985.rs:5:14
|
--> $DIR/issue-102985.rs:6:14
|
||||||
|
|
|
|
||||||
LL | n => n(),
|
LL | n => n(),
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: closures need an RFC before allowed to be called in constants
|
|
||||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// known-bug: #110395
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
pub trait A {
|
pub trait A {
|
||||||
|
@ -6,8 +8,8 @@ pub trait A {
|
||||||
|
|
||||||
pub const fn foo<T: A>() -> bool {
|
pub const fn foo<T: A>() -> bool {
|
||||||
T::assoc()
|
T::assoc()
|
||||||
//~^ ERROR the trait bound
|
//FIXME ~^ ERROR the trait bound
|
||||||
//~| ERROR cannot call non-const fn
|
//FIXME ~| ERROR cannot call non-const fn
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,24 +1,11 @@
|
||||||
error[E0277]: the trait bound `T: ~const A` is not satisfied
|
|
||||||
--> $DIR/issue-88155.rs:8:5
|
|
||||||
|
|
|
||||||
LL | T::assoc()
|
|
||||||
| ^^^^^^^^^^ the trait `~const A` is not implemented for `T`
|
|
||||||
|
|
|
||||||
note: the trait `A` is implemented for `T`, but that implementation is not `const`
|
|
||||||
--> $DIR/issue-88155.rs:8:5
|
|
||||||
|
|
|
||||||
LL | T::assoc()
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const fn `<T as A>::assoc` in constant functions
|
error[E0015]: cannot call non-const fn `<T as A>::assoc` in constant functions
|
||||||
--> $DIR/issue-88155.rs:8:5
|
--> $DIR/issue-88155.rs:10:5
|
||||||
|
|
|
|
||||||
LL | T::assoc()
|
LL | T::assoc()
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
// Regression test for #92111.
|
// Regression test for #92111.
|
||||||
//
|
//
|
||||||
// check-pass
|
// known-bug: #110395
|
||||||
|
// FIXME check-pass
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
|
11
tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr
Normal file
11
tests/ui/rfcs/rfc-2632-const-trait-impl/issue-92111.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
|
--> $DIR/issue-92111.rs:20:32
|
||||||
|
|
|
||||||
|
LL | const fn a<T: ~const Destruct>(t: T) {}
|
||||||
|
| ^ - value is dropped here
|
||||||
|
| |
|
||||||
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0493`.
|
|
@ -1,26 +1,12 @@
|
||||||
error[E0277]: can't compare `str` with `str` in const contexts
|
|
||||||
--> $DIR/match-non-const-eq.rs:6:9
|
|
||||||
|
|
|
||||||
LL | "a" => (),
|
|
||||||
| ^^^ no implementation for `str == str`
|
|
||||||
|
|
|
||||||
= help: the trait `~const PartialEq` is not implemented for `str`
|
|
||||||
note: the trait `PartialEq` is implemented for `str`, but that implementation is not `const`
|
|
||||||
--> $DIR/match-non-const-eq.rs:6:9
|
|
||||||
|
|
|
||||||
LL | "a" => (),
|
|
||||||
| ^^^
|
|
||||||
|
|
||||||
error[E0015]: cannot match on `str` in constant functions
|
error[E0015]: cannot match on `str` in constant functions
|
||||||
--> $DIR/match-non-const-eq.rs:6:9
|
--> $DIR/match-non-const-eq.rs:7:9
|
||||||
|
|
|
|
||||||
LL | "a" => (),
|
LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to previous error
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0277.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
// known-bug: #110395
|
||||||
// revisions: stock gated
|
// revisions: stock gated
|
||||||
#![cfg_attr(gated, feature(const_trait_impl))]
|
#![cfg_attr(gated, feature(const_trait_impl))]
|
||||||
|
|
||||||
const fn foo(input: &'static str) {
|
const fn foo(input: &'static str) {
|
||||||
match input {
|
match input {
|
||||||
"a" => (), //[gated]~ ERROR can't compare `str` with `str` in const contexts
|
"a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
|
||||||
//~^ ERROR cannot match on `str` in constant functions
|
//FIXME ~^ ERROR cannot match on `str` in constant functions
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
error[E0015]: cannot match on `str` in constant functions
|
error[E0015]: cannot match on `str` in constant functions
|
||||||
--> $DIR/match-non-const-eq.rs:6:9
|
--> $DIR/match-non-const-eq.rs:7:9
|
||||||
|
|
|
|
||||||
LL | "a" => (),
|
LL | "a" => (), //FIXME [gated]~ ERROR can't compare `str` with `str` in const contexts
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
|
|
||||||
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
= note: `str` cannot be compared in compile-time, and therefore cannot be used in `match`es
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Tests that trait bounds on specializing trait impls must be `~const` if the
|
// Tests that trait bounds on specializing trait impls must be `~const` if the
|
||||||
// same bound is present on the default impl and is `~const` there.
|
// same bound is present on the default impl and is `~const` there.
|
||||||
|
// known-bug: #110395
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
@ -29,7 +30,7 @@ where
|
||||||
|
|
||||||
impl<T> Bar for T
|
impl<T> Bar for T
|
||||||
where
|
where
|
||||||
T: Foo, //~ ERROR missing `~const` qualifier
|
T: Foo, //FIXME ~ ERROR missing `~const` qualifier
|
||||||
T: Specialize,
|
T: Specialize,
|
||||||
{
|
{
|
||||||
fn bar() {}
|
fn bar() {}
|
||||||
|
@ -47,7 +48,7 @@ where
|
||||||
default fn baz() {}
|
default fn baz() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> const Baz for T //~ ERROR conflicting implementations of trait `Baz`
|
impl<T> const Baz for T //FIXME ~ ERROR conflicting implementations of trait `Baz`
|
||||||
where
|
where
|
||||||
T: Foo,
|
T: Foo,
|
||||||
T: Specialize,
|
T: Specialize,
|
||||||
|
|
|
@ -1,18 +1,14 @@
|
||||||
error: missing `~const` qualifier for specialization
|
error: missing `~const` qualifier for specialization
|
||||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:32:8
|
--> $DIR/const-default-bound-non-const-specialized-bound.rs:33:8
|
||||||
|
|
|
||||||
|
LL | T: Foo, //FIXME ~ ERROR missing `~const` qualifier
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: missing `~const` qualifier for specialization
|
||||||
|
--> $DIR/const-default-bound-non-const-specialized-bound.rs:53:8
|
||||||
|
|
|
|
||||||
LL | T: Foo,
|
LL | T: Foo,
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error[E0119]: conflicting implementations of trait `Baz`
|
|
||||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:50:1
|
|
||||||
|
|
|
||||||
LL | impl<T> const Baz for T
|
|
||||||
| ----------------------- first implementation here
|
|
||||||
...
|
|
||||||
LL | impl<T> const Baz for T
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0119`.
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![feature(const_trait_impl, min_specialization, rustc_attrs)]
|
#![feature(const_trait_impl, min_specialization, rustc_attrs)]
|
||||||
|
// known-bug: #110395
|
||||||
#[rustc_specialization_trait]
|
#[rustc_specialization_trait]
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
pub trait Sup {}
|
pub trait Sup {}
|
||||||
|
@ -25,7 +25,7 @@ impl<T: Default + ~const Sup> const A for T {
|
||||||
|
|
||||||
const fn generic<T: Default>() {
|
const fn generic<T: Default>() {
|
||||||
<T as A>::a();
|
<T as A>::a();
|
||||||
//~^ ERROR: the trait bound `T: ~const Sup` is not satisfied
|
//FIXME ~^ ERROR: the trait bound `T: ~const Sup` is not satisfied
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
error[E0277]: the trait bound `T: ~const Sup` is not satisfied
|
error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
|
||||||
--> $DIR/specializing-constness-2.rs:27:5
|
--> $DIR/specializing-constness-2.rs:27:5
|
||||||
|
|
|
|
||||||
LL | <T as A>::a();
|
LL | <T as A>::a();
|
||||||
| ^^^^^^^^^^^^^ the trait `~const Sup` is not implemented for `T`
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: required for `T` to implement `~const A`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/specializing-constness-2.rs:20:37
|
|
||||||
|
|
|
||||||
LL | impl<T: Default + ~const Sup> const A for T {
|
|
||||||
| ---------- ^ ^
|
|
||||||
| |
|
|
||||||
| unsatisfied trait bound introduced here
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | const fn generic<T: Default + ~const Sup>() {
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
// known-bug: #110395
|
||||||
// revisions: yy yn ny nn
|
// revisions: yy yn ny nn
|
||||||
|
|
||||||
#[cfg_attr(any(yy, yn), const_trait)]
|
#[cfg_attr(any(yy, yn), const_trait)]
|
||||||
|
@ -9,12 +9,12 @@ trait Foo {
|
||||||
|
|
||||||
#[cfg_attr(any(yy, ny), const_trait)]
|
#[cfg_attr(any(yy, ny), const_trait)]
|
||||||
trait Bar: ~const Foo {}
|
trait Bar: ~const Foo {}
|
||||||
//[ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
|
// FIXME [ny,nn]~^ ERROR: ~const can only be applied to `#[const_trait]`
|
||||||
//[ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]`
|
// FIXME [ny,nn]~| ERROR: ~const can only be applied to `#[const_trait]`
|
||||||
|
|
||||||
const fn foo<T: Bar>(x: &T) {
|
const fn foo<T: Bar>(x: &T) {
|
||||||
x.a();
|
x.a();
|
||||||
//[yn,yy]~^ ERROR the trait bound
|
// FIXME [yn,yy]~^ ERROR the trait bound
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
|
error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
|
||||||
--> $DIR/super-traits-fail-2.rs:16:7
|
--> $DIR/super-traits-fail-2.rs:16:7
|
||||||
|
|
|
|
||||||
LL | x.a();
|
LL | x.a();
|
||||||
| ^ the trait `~const Foo` is not implemented for `T`
|
| ^^^
|
||||||
|
|
|
|
||||||
note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/super-traits-fail-2.rs:16:5
|
|
||||||
|
|
|
||||||
LL | x.a();
|
|
||||||
| ^
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | const fn foo<T: Bar + ~const Foo>(x: &T) {
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,19 +1,11 @@
|
||||||
error[E0277]: the trait bound `T: ~const Foo` is not satisfied
|
error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
|
||||||
--> $DIR/super-traits-fail-2.rs:16:7
|
--> $DIR/super-traits-fail-2.rs:16:7
|
||||||
|
|
|
|
||||||
LL | x.a();
|
LL | x.a();
|
||||||
| ^ the trait `~const Foo` is not implemented for `T`
|
| ^^^
|
||||||
|
|
|
|
||||||
note: the trait `Foo` is implemented for `T`, but that implementation is not `const`
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
--> $DIR/super-traits-fail-2.rs:16:5
|
|
||||||
|
|
|
||||||
LL | x.a();
|
|
||||||
| ^
|
|
||||||
help: consider further restricting this bound
|
|
||||||
|
|
|
||||||
LL | const fn foo<T: Bar + ~const Foo>(x: &T) {
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
// check-pass
|
||||||
|
// known-bug: #110395
|
||||||
|
|
||||||
#![feature(const_trait_impl)]
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
#[const_trait]
|
#[const_trait]
|
||||||
|
@ -13,6 +16,6 @@ impl Foo for S {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl const Bar for S {}
|
impl const Bar for S {}
|
||||||
//~^ ERROR the trait bound
|
//FIXME ~^ ERROR the trait bound
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
error[E0277]: the trait bound `S: ~const Foo` is not satisfied
|
|
||||||
--> $DIR/super-traits-fail.rs:15:20
|
|
||||||
|
|
|
||||||
LL | impl const Bar for S {}
|
|
||||||
| ^ the trait `~const Foo` is not implemented for `S`
|
|
||||||
|
|
|
||||||
note: the trait `Foo` is implemented for `S`, but that implementation is not `const`
|
|
||||||
--> $DIR/super-traits-fail.rs:15:20
|
|
||||||
|
|
|
||||||
LL | impl const Bar for S {}
|
|
||||||
| ^
|
|
||||||
note: required by a bound in `Bar`
|
|
||||||
--> $DIR/super-traits-fail.rs:8:12
|
|
||||||
|
|
|
||||||
LL | trait Bar: ~const Foo {}
|
|
||||||
| ^^^^^^^^^^ required by this bound in `Bar`
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue