Implement const effect predicate in new solver
This commit is contained in:
parent
a16d491054
commit
cde29b9ec9
127 changed files with 1702 additions and 1170 deletions
|
@ -81,6 +81,17 @@ impl<'tcx> Bounds<'tcx> {
|
||||||
self.clauses.insert(0, (trait_ref.upcast(tcx), span));
|
self.clauses.insert(0, (trait_ref.upcast(tcx), span));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Push a `const` or `~const` bound as a `HostEffect` predicate.
|
||||||
|
pub(crate) fn push_const_bound(
|
||||||
|
&mut self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
bound_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||||
|
host: ty::HostPolarity,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
|
self.clauses.push((bound_trait_ref.to_host_effect_clause(tcx, host), span));
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn clauses(
|
pub(crate) fn clauses(
|
||||||
&self,
|
&self,
|
||||||
// FIXME(effects): remove tcx
|
// FIXME(effects): remove tcx
|
||||||
|
|
|
@ -181,6 +181,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create mapping from trait method to impl method.
|
// Create mapping from trait method to impl method.
|
||||||
|
let impl_def_id = impl_m.container_id(tcx);
|
||||||
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
|
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_m.def_id).rebase_onto(
|
||||||
tcx,
|
tcx,
|
||||||
impl_m.container_id(tcx),
|
impl_m.container_id(tcx),
|
||||||
|
@ -204,6 +205,24 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
|
trait_m_predicates.instantiate_own(tcx, trait_to_impl_args).map(|(predicate, _)| predicate),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// FIXME(effects): This should be replaced with a more dedicated method.
|
||||||
|
let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const;
|
||||||
|
if check_const_if_const {
|
||||||
|
// Augment the hybrid param-env with the const conditions
|
||||||
|
// of the impl header and the trait method.
|
||||||
|
hybrid_preds.extend(
|
||||||
|
tcx.const_conditions(impl_def_id)
|
||||||
|
.instantiate_identity(tcx)
|
||||||
|
.into_iter()
|
||||||
|
.chain(
|
||||||
|
tcx.const_conditions(trait_m.def_id).instantiate_own(tcx, trait_to_impl_args),
|
||||||
|
)
|
||||||
|
.map(|(trait_ref, _)| {
|
||||||
|
trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
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(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
|
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
|
||||||
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);
|
||||||
|
@ -230,6 +249,34 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we're within a const implementation, we need to make sure that the method
|
||||||
|
// does not assume stronger `~const` bounds than the trait definition.
|
||||||
|
//
|
||||||
|
// This registers the `~const` bounds of the impl method, which we will prove
|
||||||
|
// using the hybrid param-env that we earlier augmented with the const conditions
|
||||||
|
// from the impl header and trait method declaration.
|
||||||
|
if check_const_if_const {
|
||||||
|
for (const_condition, span) in
|
||||||
|
tcx.const_conditions(impl_m.def_id).instantiate_own_identity()
|
||||||
|
{
|
||||||
|
let normalize_cause = traits::ObligationCause::misc(span, impl_m_def_id);
|
||||||
|
let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
|
||||||
|
|
||||||
|
let cause =
|
||||||
|
ObligationCause::new(span, impl_m_def_id, ObligationCauseCode::CompareImplItem {
|
||||||
|
impl_item_def_id: impl_m_def_id,
|
||||||
|
trait_item_def_id: trait_m.def_id,
|
||||||
|
kind: impl_m.kind,
|
||||||
|
});
|
||||||
|
ocx.register_obligation(traits::Obligation::new(
|
||||||
|
tcx,
|
||||||
|
cause,
|
||||||
|
param_env,
|
||||||
|
const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// We now need to check that the signature of the impl method is
|
// We now need to check that the signature of the impl method is
|
||||||
// compatible with that of the trait method. We do this by
|
// compatible with that of the trait method. We do this by
|
||||||
// checking that `impl_fty <: trait_fty`.
|
// checking that `impl_fty <: trait_fty`.
|
||||||
|
@ -1846,9 +1893,10 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
trait_ty: ty::AssocItem,
|
trait_ty: ty::AssocItem,
|
||||||
impl_trait_ref: ty::TraitRef<'tcx>,
|
impl_trait_ref: ty::TraitRef<'tcx>,
|
||||||
) -> Result<(), ErrorGuaranteed> {
|
) -> Result<(), ErrorGuaranteed> {
|
||||||
|
let impl_def_id = impl_ty.container_id(tcx);
|
||||||
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto(
|
let trait_to_impl_args = GenericArgs::identity_for_item(tcx, impl_ty.def_id).rebase_onto(
|
||||||
tcx,
|
tcx,
|
||||||
impl_ty.container_id(tcx),
|
impl_def_id,
|
||||||
impl_trait_ref.args,
|
impl_trait_ref.args,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1856,7 +1904,9 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
|
let trait_ty_predicates = tcx.predicates_of(trait_ty.def_id);
|
||||||
|
|
||||||
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity();
|
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own_identity();
|
||||||
if impl_ty_own_bounds.len() == 0 {
|
let impl_ty_own_const_conditions =
|
||||||
|
tcx.const_conditions(impl_ty.def_id).instantiate_own_identity();
|
||||||
|
if impl_ty_own_bounds.len() == 0 && impl_ty_own_const_conditions.len() == 0 {
|
||||||
// Nothing to check.
|
// Nothing to check.
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
@ -1881,6 +1931,23 @@ 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 = ObligationCause::misc(impl_ty_span, impl_ty_def_id);
|
let normalize_cause = ObligationCause::misc(impl_ty_span, impl_ty_def_id);
|
||||||
|
|
||||||
|
let check_const_if_const = tcx.constness(impl_def_id) == hir::Constness::Const;
|
||||||
|
if check_const_if_const {
|
||||||
|
// Augment the hybrid param-env with the const conditions
|
||||||
|
// of the impl header and the trait assoc type.
|
||||||
|
hybrid_preds.extend(
|
||||||
|
tcx.const_conditions(impl_ty_predicates.parent.unwrap())
|
||||||
|
.instantiate_identity(tcx)
|
||||||
|
.into_iter()
|
||||||
|
.chain(
|
||||||
|
tcx.const_conditions(trait_ty.def_id).instantiate_own(tcx, trait_to_impl_args),
|
||||||
|
)
|
||||||
|
.map(|(trait_ref, _)| {
|
||||||
|
trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
|
let param_env = ty::ParamEnv::new(tcx.mk_clauses(&hybrid_preds), Reveal::UserFacing);
|
||||||
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);
|
||||||
debug!(caller_bounds=?param_env.caller_bounds());
|
debug!(caller_bounds=?param_env.caller_bounds());
|
||||||
|
@ -1901,6 +1968,27 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||||
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
ocx.register_obligation(traits::Obligation::new(tcx, cause, param_env, predicate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if check_const_if_const {
|
||||||
|
// Validate the const conditions of the impl associated type.
|
||||||
|
for (const_condition, span) in impl_ty_own_const_conditions {
|
||||||
|
let normalize_cause = traits::ObligationCause::misc(span, impl_ty_def_id);
|
||||||
|
let const_condition = ocx.normalize(&normalize_cause, param_env, const_condition);
|
||||||
|
|
||||||
|
let cause =
|
||||||
|
ObligationCause::new(span, impl_ty_def_id, ObligationCauseCode::CompareImplItem {
|
||||||
|
impl_item_def_id: impl_ty_def_id,
|
||||||
|
trait_item_def_id: trait_ty.def_id,
|
||||||
|
kind: impl_ty.kind,
|
||||||
|
});
|
||||||
|
ocx.register_obligation(traits::Obligation::new(
|
||||||
|
tcx,
|
||||||
|
cause,
|
||||||
|
param_env,
|
||||||
|
const_condition.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check that all obligations are satisfied by the implementation's
|
// Check that all obligations are satisfied by the implementation's
|
||||||
// version.
|
// version.
|
||||||
let errors = ocx.select_all_or_error();
|
let errors = ocx.select_all_or_error();
|
||||||
|
@ -1983,7 +2071,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
ObligationCause::new(impl_ty_span, impl_ty_def_id, code)
|
ObligationCause::new(impl_ty_span, impl_ty_def_id, code)
|
||||||
};
|
};
|
||||||
|
|
||||||
let obligations: Vec<_> = tcx
|
let mut obligations: Vec<_> = tcx
|
||||||
.explicit_item_bounds(trait_ty.def_id)
|
.explicit_item_bounds(trait_ty.def_id)
|
||||||
.iter_instantiated_copied(tcx, rebased_args)
|
.iter_instantiated_copied(tcx, rebased_args)
|
||||||
.map(|(concrete_ty_bound, span)| {
|
.map(|(concrete_ty_bound, span)| {
|
||||||
|
@ -1991,6 +2079,22 @@ pub(super) fn check_type_bounds<'tcx>(
|
||||||
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
|
traits::Obligation::new(tcx, mk_cause(span), param_env, concrete_ty_bound)
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
// Only in a const implementation do we need to check that the `~const` item bounds hold.
|
||||||
|
if tcx.constness(container_id) == hir::Constness::Const {
|
||||||
|
obligations.extend(
|
||||||
|
tcx.implied_const_bounds(trait_ty.def_id)
|
||||||
|
.iter_instantiated_copied(tcx, rebased_args)
|
||||||
|
.map(|(c, span)| {
|
||||||
|
traits::Obligation::new(
|
||||||
|
tcx,
|
||||||
|
mk_cause(span),
|
||||||
|
param_env,
|
||||||
|
c.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
debug!(item_bounds=?obligations);
|
debug!(item_bounds=?obligations);
|
||||||
|
|
||||||
// Normalize predicates with the assumption that the GAT may always normalize
|
// Normalize predicates with the assumption that the GAT may always normalize
|
||||||
|
|
|
@ -32,7 +32,8 @@ use rustc_trait_selection::traits::misc::{
|
||||||
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||||
use rustc_trait_selection::traits::{
|
use rustc_trait_selection::traits::{
|
||||||
self, FulfillmentError, ObligationCause, ObligationCauseCode, ObligationCtxt, WellFormedLoc,
|
self, FulfillmentError, Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
|
||||||
|
WellFormedLoc,
|
||||||
};
|
};
|
||||||
use rustc_type_ir::TypeFlags;
|
use rustc_type_ir::TypeFlags;
|
||||||
use rustc_type_ir::solve::NoSolution;
|
use rustc_type_ir::solve::NoSolution;
|
||||||
|
@ -86,7 +87,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
self.body_def_id,
|
self.body_def_id,
|
||||||
ObligationCauseCode::WellFormed(loc),
|
ObligationCauseCode::WellFormed(loc),
|
||||||
);
|
);
|
||||||
self.ocx.register_obligation(traits::Obligation::new(
|
self.ocx.register_obligation(Obligation::new(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
cause,
|
cause,
|
||||||
self.param_env,
|
self.param_env,
|
||||||
|
@ -1173,7 +1174,7 @@ fn check_type_defn<'tcx>(
|
||||||
wfcx.body_def_id,
|
wfcx.body_def_id,
|
||||||
ObligationCauseCode::Misc,
|
ObligationCauseCode::Misc,
|
||||||
);
|
);
|
||||||
wfcx.register_obligation(traits::Obligation::new(
|
wfcx.register_obligation(Obligation::new(
|
||||||
tcx,
|
tcx,
|
||||||
cause,
|
cause,
|
||||||
wfcx.param_env,
|
wfcx.param_env,
|
||||||
|
@ -1369,6 +1370,30 @@ fn check_impl<'tcx>(
|
||||||
obligation.cause.span = hir_self_ty.span;
|
obligation.cause.span = hir_self_ty.span;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Ensure that the `~const` where clauses of the trait hold for the impl.
|
||||||
|
if tcx.constness(item.owner_id.def_id) == hir::Constness::Const {
|
||||||
|
for (bound, _) in
|
||||||
|
tcx.const_conditions(trait_ref.def_id).instantiate(tcx, trait_ref.args)
|
||||||
|
{
|
||||||
|
let bound = wfcx.normalize(
|
||||||
|
item.span,
|
||||||
|
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||||
|
bound,
|
||||||
|
);
|
||||||
|
wfcx.register_obligation(Obligation::new(
|
||||||
|
tcx,
|
||||||
|
ObligationCause::new(
|
||||||
|
hir_self_ty.span,
|
||||||
|
wfcx.body_def_id,
|
||||||
|
ObligationCauseCode::WellFormed(None),
|
||||||
|
),
|
||||||
|
wfcx.param_env,
|
||||||
|
bound.to_host_effect_clause(tcx, ty::HostPolarity::Maybe),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
debug!(?obligations);
|
debug!(?obligations);
|
||||||
wfcx.register_obligations(obligations);
|
wfcx.register_obligations(obligations);
|
||||||
}
|
}
|
||||||
|
@ -1561,7 +1586,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
wfcx.body_def_id,
|
wfcx.body_def_id,
|
||||||
ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP),
|
ObligationCauseCode::WhereClause(def_id.to_def_id(), DUMMY_SP),
|
||||||
);
|
);
|
||||||
traits::Obligation::new(tcx, cause, wfcx.param_env, pred)
|
Obligation::new(tcx, cause, wfcx.param_env, pred)
|
||||||
});
|
});
|
||||||
|
|
||||||
let predicates = predicates.instantiate_identity(tcx);
|
let predicates = predicates.instantiate_identity(tcx);
|
||||||
|
@ -1852,7 +1877,7 @@ fn receiver_is_implemented<'tcx>(
|
||||||
let tcx = wfcx.tcx();
|
let tcx = wfcx.tcx();
|
||||||
let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]);
|
let trait_ref = ty::TraitRef::new(tcx, receiver_trait_def_id, [receiver_ty]);
|
||||||
|
|
||||||
let obligation = traits::Obligation::new(tcx, cause, wfcx.param_env, trait_ref);
|
let obligation = Obligation::new(tcx, cause, wfcx.param_env, trait_ref);
|
||||||
|
|
||||||
if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) {
|
if wfcx.infcx.predicate_must_hold_modulo_regions(&obligation) {
|
||||||
true
|
true
|
||||||
|
@ -2188,7 +2213,7 @@ impl<'tcx> WfCheckingCtxt<'_, 'tcx> {
|
||||||
.unwrap_or(obligation_span);
|
.unwrap_or(obligation_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
let obligation = traits::Obligation::new(
|
let obligation = Obligation::new(
|
||||||
tcx,
|
tcx,
|
||||||
traits::ObligationCause::new(
|
traits::ObligationCause::new(
|
||||||
span,
|
span,
|
||||||
|
|
|
@ -77,6 +77,8 @@ pub fn provide(providers: &mut Providers) {
|
||||||
explicit_supertraits_containing_assoc_item:
|
explicit_supertraits_containing_assoc_item:
|
||||||
predicates_of::explicit_supertraits_containing_assoc_item,
|
predicates_of::explicit_supertraits_containing_assoc_item,
|
||||||
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
||||||
|
const_conditions: predicates_of::const_conditions,
|
||||||
|
implied_const_bounds: predicates_of::implied_const_bounds,
|
||||||
type_param_predicates: predicates_of::type_param_predicates,
|
type_param_predicates: predicates_of::type_param_predicates,
|
||||||
trait_def,
|
trait_def,
|
||||||
adt_def,
|
adt_def,
|
||||||
|
|
|
@ -40,7 +40,16 @@ fn associated_type_bounds<'tcx>(
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
|
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
|
||||||
// Associated types are implicitly sized unless a `?Sized` bound is found
|
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||||
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
|
match filter {
|
||||||
|
PredicateFilter::All
|
||||||
|
| PredicateFilter::SelfOnly
|
||||||
|
| PredicateFilter::SelfThatDefines(_)
|
||||||
|
| PredicateFilter::SelfAndAssociatedTypeBounds => {
|
||||||
|
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
|
||||||
|
}
|
||||||
|
// `ConstIfConst` is only interested in `~const` bounds.
|
||||||
|
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
|
||||||
|
}
|
||||||
|
|
||||||
let trait_def_id = tcx.local_parent(assoc_item_def_id);
|
let trait_def_id = tcx.local_parent(assoc_item_def_id);
|
||||||
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
|
let trait_predicates = tcx.trait_explicit_predicates_and_bounds(trait_def_id);
|
||||||
|
@ -109,10 +118,19 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
|
||||||
} else {
|
} else {
|
||||||
// Only collect *self* type bounds if the filter is for self.
|
// Only collect *self* type bounds if the filter is for self.
|
||||||
match filter {
|
match filter {
|
||||||
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
|
PredicateFilter::All => {}
|
||||||
|
PredicateFilter::SelfOnly => {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {}
|
PredicateFilter::SelfThatDefines(_)
|
||||||
|
| PredicateFilter::SelfConstIfConst
|
||||||
|
| PredicateFilter::SelfAndAssociatedTypeBounds
|
||||||
|
| PredicateFilter::ConstIfConst => {
|
||||||
|
unreachable!(
|
||||||
|
"invalid predicate filter for \
|
||||||
|
`remap_gat_vars_and_recurse_into_nested_projections`"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
clause_ty = alias_ty.self_ty();
|
clause_ty = alias_ty.self_ty();
|
||||||
|
@ -308,7 +326,17 @@ fn opaque_type_bounds<'tcx>(
|
||||||
let mut bounds = Bounds::default();
|
let mut bounds = Bounds::default();
|
||||||
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
|
icx.lowerer().lower_bounds(item_ty, hir_bounds, &mut bounds, ty::List::empty(), filter);
|
||||||
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
// Opaque types are implicitly sized unless a `?Sized` bound is found
|
||||||
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
|
match filter {
|
||||||
|
PredicateFilter::All
|
||||||
|
| PredicateFilter::SelfOnly
|
||||||
|
| PredicateFilter::SelfThatDefines(_)
|
||||||
|
| PredicateFilter::SelfAndAssociatedTypeBounds => {
|
||||||
|
// Associated types are implicitly sized unless a `?Sized` bound is found
|
||||||
|
icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
|
||||||
|
}
|
||||||
|
//`ConstIfConst` is only interested in `~const` bounds.
|
||||||
|
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
|
||||||
|
}
|
||||||
debug!(?bounds);
|
debug!(?bounds);
|
||||||
|
|
||||||
tcx.arena.alloc_from_iter(bounds.clauses(tcx))
|
tcx.arena.alloc_from_iter(bounds.clauses(tcx))
|
||||||
|
|
|
@ -12,6 +12,7 @@ use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{DUMMY_SP, Span};
|
use rustc_span::{DUMMY_SP, Span};
|
||||||
use tracing::{debug, instrument, trace};
|
use tracing::{debug, instrument, trace};
|
||||||
|
|
||||||
|
use super::item_bounds::explicit_item_bounds_with_filter;
|
||||||
use crate::bounds::Bounds;
|
use crate::bounds::Bounds;
|
||||||
use crate::collect::ItemCtxt;
|
use crate::collect::ItemCtxt;
|
||||||
use crate::constrained_generic_params as cgp;
|
use crate::constrained_generic_params as cgp;
|
||||||
|
@ -685,29 +686,76 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
trait_predicate.self_ty(),
|
trait_predicate.self_ty(),
|
||||||
ty,
|
ty,
|
||||||
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
"expected `Self` predicate when computing \
|
||||||
|
`{filter:?}` implied bounds: {clause:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ty::ClauseKind::Projection(projection_predicate) => {
|
ty::ClauseKind::Projection(projection_predicate) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
projection_predicate.self_ty(),
|
projection_predicate.self_ty(),
|
||||||
ty,
|
ty,
|
||||||
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
"expected `Self` predicate when computing \
|
||||||
|
`{filter:?}` implied bounds: {clause:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ty::ClauseKind::TypeOutlives(outlives_predicate) => {
|
ty::ClauseKind::TypeOutlives(outlives_predicate) => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
outlives_predicate.0, ty,
|
outlives_predicate.0, ty,
|
||||||
"expected `Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
"expected `Self` predicate when computing \
|
||||||
|
`{filter:?}` implied bounds: {clause:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::ClauseKind::RegionOutlives(_)
|
ty::ClauseKind::RegionOutlives(_)
|
||||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::ClauseKind::WellFormed(_)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::ClauseKind::ConstEvaluatable(_) => {
|
| ty::ClauseKind::ConstEvaluatable(_)
|
||||||
|
| ty::ClauseKind::HostEffect(..) => {
|
||||||
bug!(
|
bug!(
|
||||||
"unexpected non-`Self` predicate when computing `{filter:?}` implied bounds: {clause:?}"
|
"unexpected non-`Self` predicate when computing \
|
||||||
|
`{filter:?}` implied bounds: {clause:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PredicateFilter::ConstIfConst => {
|
||||||
|
for (clause, _) in bounds {
|
||||||
|
match clause.kind().skip_binder() {
|
||||||
|
ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
|
||||||
|
trait_ref: _,
|
||||||
|
host: ty::HostPolarity::Maybe,
|
||||||
|
}) => {}
|
||||||
|
_ => {
|
||||||
|
bug!(
|
||||||
|
"unexpected non-`HostEffect` predicate when computing \
|
||||||
|
`{filter:?}` implied bounds: {clause:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PredicateFilter::SelfConstIfConst => {
|
||||||
|
for (clause, _) in bounds {
|
||||||
|
match clause.kind().skip_binder() {
|
||||||
|
ty::ClauseKind::HostEffect(pred) => {
|
||||||
|
assert_eq!(
|
||||||
|
pred.host,
|
||||||
|
ty::HostPolarity::Maybe,
|
||||||
|
"expected `~const` predicate when computing `{filter:?}` \
|
||||||
|
implied bounds: {clause:?}",
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
pred.trait_ref.self_ty(),
|
||||||
|
ty,
|
||||||
|
"expected `Self` predicate when computing `{filter:?}` \
|
||||||
|
implied bounds: {clause:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bug!(
|
||||||
|
"unexpected non-`HostEffect` predicate when computing \
|
||||||
|
`{filter:?}` implied bounds: {clause:?}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -829,3 +877,184 @@ impl<'tcx> ItemCtxt<'tcx> {
|
||||||
bounds.clauses(self.tcx).collect()
|
bounds.clauses(self.tcx).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compute the conditions that need to hold for a conditionally-const item to be const.
|
||||||
|
/// That is, compute the set of `~const` where clauses for a given item.
|
||||||
|
///
|
||||||
|
/// This query also computes the `~const` where clauses for associated types, which are
|
||||||
|
/// not "const", but which have item bounds which may be `~const`. These must hold for
|
||||||
|
/// the `~const` item bound to hold.
|
||||||
|
pub(super) fn const_conditions<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) -> ty::ConstConditions<'tcx> {
|
||||||
|
// This logic is spaghetti, and should be cleaned up. The current methods that are
|
||||||
|
// defined to deal with constness are very unintuitive.
|
||||||
|
if tcx.is_const_fn_raw(def_id.to_def_id()) {
|
||||||
|
// Ok, const fn or method in const trait.
|
||||||
|
} else {
|
||||||
|
match tcx.def_kind(def_id) {
|
||||||
|
DefKind::Trait => {
|
||||||
|
if !tcx.is_const_trait(def_id.to_def_id()) {
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefKind::Impl { .. } => {
|
||||||
|
// FIXME(effects): Should be using a dedicated function to
|
||||||
|
// test if this is a const trait impl.
|
||||||
|
if tcx.constness(def_id) != hir::Constness::Const {
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefKind::AssocTy | DefKind::AssocFn => {
|
||||||
|
let parent_def_id = tcx.local_parent(def_id).to_def_id();
|
||||||
|
match tcx.associated_item(def_id).container {
|
||||||
|
ty::AssocItemContainer::TraitContainer => {
|
||||||
|
if !tcx.is_const_trait(parent_def_id) {
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::AssocItemContainer::ImplContainer => {
|
||||||
|
// FIXME(effects): Should be using a dedicated function to
|
||||||
|
// test if this is a const trait impl.
|
||||||
|
if tcx.constness(parent_def_id) != hir::Constness::Const {
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DefKind::Closure | DefKind::OpaqueTy => {
|
||||||
|
// Closures and RPITs will eventually have const conditions
|
||||||
|
// for `~const` bounds.
|
||||||
|
return Default::default();
|
||||||
|
}
|
||||||
|
_ => return Default::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let (generics, trait_def_id_and_supertraits, has_parent) = match tcx.hir_node_by_def_id(def_id)
|
||||||
|
{
|
||||||
|
Node::Item(item) => match item.kind {
|
||||||
|
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
|
||||||
|
hir::ItemKind::Fn(_, generics, _) => (generics, None, false),
|
||||||
|
hir::ItemKind::Trait(_, _, generics, supertraits, _) => {
|
||||||
|
(generics, Some((item.owner_id.def_id, supertraits)), false)
|
||||||
|
}
|
||||||
|
_ => return Default::default(),
|
||||||
|
},
|
||||||
|
// While associated types are not really const, we do allow them to have `~const`
|
||||||
|
// bounds and where clauses. `const_conditions` is responsible for gathering
|
||||||
|
// these up so we can check them in `compare_type_predicate_entailment`, and
|
||||||
|
// in `HostEffect` goal computation.
|
||||||
|
Node::TraitItem(item) => match item.kind {
|
||||||
|
hir::TraitItemKind::Fn(_, _) | hir::TraitItemKind::Type(_, _) => {
|
||||||
|
(item.generics, None, true)
|
||||||
|
}
|
||||||
|
_ => return Default::default(),
|
||||||
|
},
|
||||||
|
Node::ImplItem(item) => match item.kind {
|
||||||
|
hir::ImplItemKind::Fn(_, _) | hir::ImplItemKind::Type(_) => (item.generics, None, true),
|
||||||
|
_ => return Default::default(),
|
||||||
|
},
|
||||||
|
_ => return Default::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let icx = ItemCtxt::new(tcx, def_id);
|
||||||
|
let mut bounds = Bounds::default();
|
||||||
|
|
||||||
|
for pred in generics.predicates {
|
||||||
|
match pred {
|
||||||
|
hir::WherePredicate::BoundPredicate(bound_pred) => {
|
||||||
|
let ty = icx.lowerer().lower_ty_maybe_return_type_notation(bound_pred.bounded_ty);
|
||||||
|
let bound_vars = tcx.late_bound_vars(bound_pred.hir_id);
|
||||||
|
icx.lowerer().lower_bounds(
|
||||||
|
ty,
|
||||||
|
bound_pred.bounds.iter(),
|
||||||
|
&mut bounds,
|
||||||
|
bound_vars,
|
||||||
|
PredicateFilter::ConstIfConst,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some((def_id, supertraits)) = trait_def_id_and_supertraits {
|
||||||
|
bounds.push_const_bound(
|
||||||
|
tcx,
|
||||||
|
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id())),
|
||||||
|
ty::HostPolarity::Maybe,
|
||||||
|
DUMMY_SP,
|
||||||
|
);
|
||||||
|
|
||||||
|
icx.lowerer().lower_bounds(
|
||||||
|
tcx.types.self_param,
|
||||||
|
supertraits.into_iter(),
|
||||||
|
&mut bounds,
|
||||||
|
ty::List::empty(),
|
||||||
|
PredicateFilter::ConstIfConst,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ty::ConstConditions {
|
||||||
|
parent: has_parent.then(|| tcx.local_parent(def_id).to_def_id()),
|
||||||
|
predicates: tcx.arena.alloc_from_iter(bounds.clauses(tcx).map(|(clause, span)| {
|
||||||
|
(
|
||||||
|
clause.kind().map_bound(|clause| match clause {
|
||||||
|
ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
|
||||||
|
trait_ref,
|
||||||
|
host: ty::HostPolarity::Maybe,
|
||||||
|
}) => trait_ref,
|
||||||
|
_ => bug!("converted {clause:?}"),
|
||||||
|
}),
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(super) fn implied_const_bounds<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
def_id: LocalDefId,
|
||||||
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||||
|
let bounds = match tcx.hir_node_by_def_id(def_id) {
|
||||||
|
Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
|
||||||
|
if !tcx.is_const_trait(def_id.to_def_id()) {
|
||||||
|
return ty::EarlyBinder::bind(&[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
implied_predicates_with_filter(
|
||||||
|
tcx,
|
||||||
|
def_id.to_def_id(),
|
||||||
|
PredicateFilter::SelfConstIfConst,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => {
|
||||||
|
if !tcx.is_const_trait(tcx.local_parent(def_id).to_def_id()) {
|
||||||
|
return ty::EarlyBinder::bind(&[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
|
||||||
|
}
|
||||||
|
Node::OpaqueTy(..) => {
|
||||||
|
// We should eventually collect the `~const` bounds on opaques.
|
||||||
|
return ty::EarlyBinder::bind(&[]);
|
||||||
|
}
|
||||||
|
_ => return ty::EarlyBinder::bind(&[]),
|
||||||
|
};
|
||||||
|
|
||||||
|
bounds.map_bound(|bounds| {
|
||||||
|
&*tcx.arena.alloc_from_iter(bounds.iter().copied().map(|(clause, span)| {
|
||||||
|
(
|
||||||
|
clause.kind().map_bound(|clause| match clause {
|
||||||
|
ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
|
||||||
|
trait_ref,
|
||||||
|
host: ty::HostPolarity::Maybe,
|
||||||
|
}) => trait_ref,
|
||||||
|
_ => bug!("converted {clause:?}"),
|
||||||
|
}),
|
||||||
|
span,
|
||||||
|
)
|
||||||
|
}))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -154,7 +154,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
for hir_bound in hir_bounds {
|
for hir_bound in hir_bounds {
|
||||||
// In order to avoid cycles, when we're lowering `SelfThatDefines`,
|
// In order to avoid cycles, when we're lowering `SelfThatDefines`,
|
||||||
// we skip over any traits that don't define the given associated type.
|
// we skip over any traits that don't define the given associated type.
|
||||||
|
|
||||||
if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter {
|
if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter {
|
||||||
if let Some(trait_ref) = hir_bound.trait_ref()
|
if let Some(trait_ref) = hir_bound.trait_ref()
|
||||||
&& let Some(trait_did) = trait_ref.trait_def_id()
|
&& let Some(trait_did) = trait_ref.trait_def_id()
|
||||||
|
@ -193,6 +192,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
hir::GenericBound::Outlives(lifetime) => {
|
hir::GenericBound::Outlives(lifetime) => {
|
||||||
|
// `ConstIfConst` is only interested in `~const` bounds.
|
||||||
|
if matches!(
|
||||||
|
predicate_filter,
|
||||||
|
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
|
let region = self.lower_lifetime(lifetime, RegionInferReason::OutlivesBound);
|
||||||
bounds.push_region_bound(
|
bounds.push_region_bound(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
|
@ -392,21 +399,31 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
bounds.push_projection_bound(
|
match predicate_filter {
|
||||||
tcx,
|
PredicateFilter::All
|
||||||
projection_term.map_bound(|projection_term| ty::ProjectionPredicate {
|
| PredicateFilter::SelfOnly
|
||||||
projection_term,
|
| PredicateFilter::SelfThatDefines(_)
|
||||||
term,
|
| PredicateFilter::SelfAndAssociatedTypeBounds => {
|
||||||
}),
|
bounds.push_projection_bound(
|
||||||
constraint.span,
|
tcx,
|
||||||
);
|
projection_term.map_bound(|projection_term| ty::ProjectionPredicate {
|
||||||
|
projection_term,
|
||||||
|
term,
|
||||||
|
}),
|
||||||
|
constraint.span,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// `ConstIfConst` is only interested in `~const` bounds.
|
||||||
|
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
// Lower a constraint like `Item: Debug` as found in HIR bound `T: Iterator<Item: Debug>`
|
||||||
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
// to a bound involving a projection: `<T as Iterator>::Item: Debug`.
|
||||||
hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
|
hir::AssocItemConstraintKind::Bound { bounds: hir_bounds } => {
|
||||||
match predicate_filter {
|
match predicate_filter {
|
||||||
PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {}
|
PredicateFilter::All
|
||||||
PredicateFilter::All | PredicateFilter::SelfAndAssociatedTypeBounds => {
|
| PredicateFilter::SelfAndAssociatedTypeBounds
|
||||||
|
| PredicateFilter::ConstIfConst => {
|
||||||
let projection_ty = projection_term
|
let projection_ty = projection_term
|
||||||
.map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
|
.map_bound(|projection_term| projection_term.expect_ty(self.tcx()));
|
||||||
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
|
// Calling `skip_binder` is okay, because `lower_bounds` expects the `param_ty`
|
||||||
|
@ -421,6 +438,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
predicate_filter,
|
predicate_filter,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
PredicateFilter::SelfOnly
|
||||||
|
| PredicateFilter::SelfThatDefines(_)
|
||||||
|
| PredicateFilter::SelfConstIfConst => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
ty::ClauseKind::RegionOutlives(_)
|
ty::ClauseKind::RegionOutlives(_)
|
||||||
| ty::ClauseKind::ConstArgHasType(..)
|
| ty::ClauseKind::ConstArgHasType(..)
|
||||||
| ty::ClauseKind::WellFormed(_)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::ClauseKind::ConstEvaluatable(_) => {
|
| ty::ClauseKind::ConstEvaluatable(_)
|
||||||
|
| ty::ClauseKind::HostEffect(..) => {
|
||||||
span_bug!(span, "did not expect {pred} clause in object bounds");
|
span_bug!(span, "did not expect {pred} clause in object bounds");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,12 @@ pub enum PredicateFilter {
|
||||||
/// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
|
/// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
|
||||||
/// and `<Self as Tr>::A: B`.
|
/// and `<Self as Tr>::A: B`.
|
||||||
SelfAndAssociatedTypeBounds,
|
SelfAndAssociatedTypeBounds,
|
||||||
|
|
||||||
|
/// Filter only the `~const` bounds, which are lowered into `HostEffect` clauses.
|
||||||
|
ConstIfConst,
|
||||||
|
|
||||||
|
/// Filter only the `~const` bounds which are *also* in the supertrait position.
|
||||||
|
SelfConstIfConst,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -693,8 +699,49 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
|
||||||
bound_vars,
|
bound_vars,
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!(?poly_trait_ref);
|
match predicate_filter {
|
||||||
bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
|
PredicateFilter::All
|
||||||
|
| PredicateFilter::SelfOnly
|
||||||
|
| PredicateFilter::SelfThatDefines(..)
|
||||||
|
| PredicateFilter::SelfAndAssociatedTypeBounds => {
|
||||||
|
debug!(?poly_trait_ref);
|
||||||
|
bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
|
||||||
|
|
||||||
|
match constness {
|
||||||
|
Some(ty::BoundConstness::Const) => {
|
||||||
|
if polarity == ty::PredicatePolarity::Positive {
|
||||||
|
bounds.push_const_bound(
|
||||||
|
tcx,
|
||||||
|
poly_trait_ref,
|
||||||
|
ty::HostPolarity::Const,
|
||||||
|
span,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(ty::BoundConstness::ConstIfConst) => {
|
||||||
|
// We don't emit a const bound here, since that would mean that we
|
||||||
|
// unconditionally need to prove a `HostEffect` predicate, even when
|
||||||
|
// the predicates are being instantiated in a non-const context. This
|
||||||
|
// is instead handled in the `const_conditions` query.
|
||||||
|
}
|
||||||
|
None => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// On the flip side, when filtering `ConstIfConst` bounds, we only need to convert
|
||||||
|
// `~const` bounds. All other predicates are handled in their respective queries.
|
||||||
|
//
|
||||||
|
// Note that like `PredicateFilter::SelfOnly`, we don't need to do any filtering
|
||||||
|
// here because we only call this on self bounds, and deal with the recursive case
|
||||||
|
// in `lower_assoc_item_constraint`.
|
||||||
|
PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => match constness {
|
||||||
|
Some(ty::BoundConstness::ConstIfConst) => {
|
||||||
|
if polarity == ty::PredicatePolarity::Positive {
|
||||||
|
bounds.push_const_bound(tcx, poly_trait_ref, ty::HostPolarity::Maybe, span);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None | Some(ty::BoundConstness::Const) => {}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
let mut dup_constraints = FxIndexMap::default();
|
let mut dup_constraints = FxIndexMap::default();
|
||||||
for constraint in trait_segment.args().constraints {
|
for constraint in trait_segment.args().constraints {
|
||||||
|
|
|
@ -530,6 +530,7 @@ fn trait_specialization_kind<'tcx>(
|
||||||
| ty::ClauseKind::Projection(_)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::ClauseKind::ConstArgHasType(..)
|
| ty::ClauseKind::ConstArgHasType(..)
|
||||||
| ty::ClauseKind::WellFormed(_)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::ClauseKind::ConstEvaluatable(..) => None,
|
| ty::ClauseKind::ConstEvaluatable(..)
|
||||||
|
| ty::ClauseKind::HostEffect(..) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,8 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
|
||||||
| ty::ClauseKind::Projection(_)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::ClauseKind::WellFormed(_)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::ClauseKind::ConstEvaluatable(_) => {}
|
| ty::ClauseKind::ConstEvaluatable(_)
|
||||||
|
| ty::ClauseKind::HostEffect(..) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -836,14 +836,51 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
fn_sig.output()
|
fn_sig.output()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "debug", skip(self, _span))]
|
#[tracing::instrument(level = "debug", skip(self, span))]
|
||||||
pub(super) fn enforce_context_effects(
|
pub(super) fn enforce_context_effects(
|
||||||
&self,
|
&self,
|
||||||
_span: Span,
|
span: Span,
|
||||||
_callee_did: DefId,
|
callee_did: DefId,
|
||||||
_callee_args: GenericArgsRef<'tcx>,
|
callee_args: GenericArgsRef<'tcx>,
|
||||||
) {
|
) {
|
||||||
todo!()
|
// FIXME(effects): We should be enforcing these effects unconditionally.
|
||||||
|
// This can be done as soon as we convert the standard library back to
|
||||||
|
// using const traits, since if we were to enforce these conditions now,
|
||||||
|
// we'd fail on basically every builtin trait call (i.e. `1 + 2`).
|
||||||
|
if !self.tcx.features().effects() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let host = match self.tcx.hir().body_const_context(self.body_id) {
|
||||||
|
Some(hir::ConstContext::Const { .. } | hir::ConstContext::Static(_)) => {
|
||||||
|
ty::HostPolarity::Const
|
||||||
|
}
|
||||||
|
Some(hir::ConstContext::ConstFn) => ty::HostPolarity::Maybe,
|
||||||
|
None => return,
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME(effects): Should this be `is_const_fn_raw`? It depends on if we move
|
||||||
|
// const stability checking here too, I guess.
|
||||||
|
if self.tcx.is_const_fn(callee_did)
|
||||||
|
|| self
|
||||||
|
.tcx
|
||||||
|
.trait_of_item(callee_did)
|
||||||
|
.is_some_and(|def_id| self.tcx.is_const_trait(def_id))
|
||||||
|
{
|
||||||
|
let q = self.tcx.const_conditions(callee_did);
|
||||||
|
// FIXME(effects): Use this span with a better cause code.
|
||||||
|
for (cond, _) in q.instantiate(self.tcx, callee_args) {
|
||||||
|
self.register_predicate(Obligation::new(
|
||||||
|
self.tcx,
|
||||||
|
self.misc(span),
|
||||||
|
self.param_env,
|
||||||
|
cond.to_host_effect_clause(self.tcx, host),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// FIXME(effects): This should eventually be caught here.
|
||||||
|
// For now, though, we defer some const checking to MIR.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn confirm_overloaded_call(
|
fn confirm_overloaded_call(
|
||||||
|
|
|
@ -52,6 +52,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..)
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
|
||||||
| ty::PredicateKind::Ambiguous => false,
|
| ty::PredicateKind::Ambiguous => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -813,7 +813,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
| ty::ClauseKind::Projection(_)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::ClauseKind::WellFormed(_)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::ClauseKind::ConstEvaluatable(_) => None,
|
| ty::ClauseKind::ConstEvaluatable(_)
|
||||||
|
| ty::ClauseKind::HostEffect(..) => None,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -24,19 +24,9 @@ pub fn explicit_outlives_bounds<'tcx>(
|
||||||
param_env
|
param_env
|
||||||
.caller_bounds()
|
.caller_bounds()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(ty::Clause::kind)
|
.filter_map(ty::Clause::as_region_outlives_clause)
|
||||||
.filter_map(ty::Binder::no_bound_vars)
|
.filter_map(ty::Binder::no_bound_vars)
|
||||||
.filter_map(move |kind| match kind {
|
.map(|ty::OutlivesPredicate(r_a, r_b)| OutlivesBound::RegionSubRegion(r_b, r_a))
|
||||||
ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(r_a, r_b)) => {
|
|
||||||
Some(OutlivesBound::RegionSubRegion(r_b, r_a))
|
|
||||||
}
|
|
||||||
ty::ClauseKind::Trait(_)
|
|
||||||
| ty::ClauseKind::TypeOutlives(_)
|
|
||||||
| ty::ClauseKind::Projection(_)
|
|
||||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
|
||||||
| ty::ClauseKind::WellFormed(_)
|
|
||||||
| ty::ClauseKind::ConstEvaluatable(_) => None,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> InferCtxt<'tcx> {
|
impl<'tcx> InferCtxt<'tcx> {
|
||||||
|
|
|
@ -1554,7 +1554,9 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
|
||||||
// Ignore bounds that a user can't type
|
// Ignore bounds that a user can't type
|
||||||
| ClauseKind::WellFormed(..)
|
| ClauseKind::WellFormed(..)
|
||||||
// FIXME(generic_const_exprs): `ConstEvaluatable` can be written
|
// FIXME(generic_const_exprs): `ConstEvaluatable` can be written
|
||||||
| ClauseKind::ConstEvaluatable(..) => continue,
|
| ClauseKind::ConstEvaluatable(..)
|
||||||
|
// Users don't write this directly, only via another trait ref.
|
||||||
|
| ty::ClauseKind::HostEffect(..) => continue,
|
||||||
};
|
};
|
||||||
if predicate.is_global() {
|
if predicate.is_global() {
|
||||||
cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds {
|
cx.emit_span_lint(TRIVIAL_BOUNDS, span, BuiltinTrivialBounds {
|
||||||
|
|
|
@ -275,6 +275,8 @@ provide! { tcx, def_id, other, cdata,
|
||||||
impl_parent => { table }
|
impl_parent => { table }
|
||||||
defaultness => { table_direct }
|
defaultness => { table_direct }
|
||||||
constness => { table_direct }
|
constness => { table_direct }
|
||||||
|
const_conditions => { table }
|
||||||
|
implied_const_bounds => { table_defaulted_array }
|
||||||
coerce_unsized_info => {
|
coerce_unsized_info => {
|
||||||
Ok(cdata
|
Ok(cdata
|
||||||
.root
|
.root
|
||||||
|
|
|
@ -1423,6 +1423,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
let g = tcx.generics_of(def_id);
|
let g = tcx.generics_of(def_id);
|
||||||
record!(self.tables.generics_of[def_id] <- g);
|
record!(self.tables.generics_of[def_id] <- g);
|
||||||
record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
|
record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id));
|
||||||
|
record!(self.tables.const_conditions[def_id] <- self.tcx.const_conditions(def_id));
|
||||||
let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
|
let inferred_outlives = self.tcx.inferred_outlives_of(def_id);
|
||||||
record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
|
record_defaulted_array!(self.tables.inferred_outlives_of[def_id] <- inferred_outlives);
|
||||||
|
|
||||||
|
@ -1456,7 +1457,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
self.tcx.explicit_super_predicates_of(def_id).skip_binder());
|
self.tcx.explicit_super_predicates_of(def_id).skip_binder());
|
||||||
record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
|
record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
|
||||||
self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
|
self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
|
||||||
|
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
||||||
|
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
||||||
let module_children = self.tcx.module_children_local(local_id);
|
let module_children = self.tcx.module_children_local(local_id);
|
||||||
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
||||||
module_children.iter().map(|child| child.res.def_id().index));
|
module_children.iter().map(|child| child.res.def_id().index));
|
||||||
|
@ -1467,6 +1469,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
self.tcx.explicit_super_predicates_of(def_id).skip_binder());
|
self.tcx.explicit_super_predicates_of(def_id).skip_binder());
|
||||||
record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
|
record_defaulted_array!(self.tables.explicit_implied_predicates_of[def_id] <-
|
||||||
self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
|
self.tcx.explicit_implied_predicates_of(def_id).skip_binder());
|
||||||
|
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
||||||
|
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
||||||
}
|
}
|
||||||
if let DefKind::Trait | DefKind::Impl { .. } = def_kind {
|
if let DefKind::Trait | DefKind::Impl { .. } = def_kind {
|
||||||
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
|
let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id);
|
||||||
|
@ -1649,6 +1653,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
||||||
if let ty::AssocKind::Type = item.kind {
|
if let ty::AssocKind::Type = item.kind {
|
||||||
self.encode_explicit_item_bounds(def_id);
|
self.encode_explicit_item_bounds(def_id);
|
||||||
self.encode_explicit_item_super_predicates(def_id);
|
self.encode_explicit_item_super_predicates(def_id);
|
||||||
|
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
||||||
|
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AssocItemContainer::ImplContainer => {
|
AssocItemContainer::ImplContainer => {
|
||||||
|
|
|
@ -392,6 +392,7 @@ define_tables! {
|
||||||
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
|
implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
|
||||||
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
|
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
|
||||||
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
|
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
|
||||||
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
|
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
|
||||||
|
@ -435,6 +436,7 @@ define_tables! {
|
||||||
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::Const<'static>>>>,
|
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<'static, ty::Const<'static>>>>,
|
||||||
impl_parent: Table<DefIndex, RawDefId>,
|
impl_parent: Table<DefIndex, RawDefId>,
|
||||||
constness: Table<DefIndex, hir::Constness>,
|
constness: Table<DefIndex, hir::Constness>,
|
||||||
|
const_conditions: Table<DefIndex, LazyValue<ty::ConstConditions<'static>>>,
|
||||||
defaultness: Table<DefIndex, hir::Defaultness>,
|
defaultness: Table<DefIndex, hir::Defaultness>,
|
||||||
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
|
// FIXME(eddyb) perhaps compute this on the fly if cheap enough?
|
||||||
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
|
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
|
||||||
|
|
|
@ -370,6 +370,7 @@ tcx_lifetime! {
|
||||||
rustc_middle::ty::FnSig,
|
rustc_middle::ty::FnSig,
|
||||||
rustc_middle::ty::GenericArg,
|
rustc_middle::ty::GenericArg,
|
||||||
rustc_middle::ty::GenericPredicates,
|
rustc_middle::ty::GenericPredicates,
|
||||||
|
rustc_middle::ty::ConstConditions,
|
||||||
rustc_middle::ty::inhabitedness::InhabitedPredicate,
|
rustc_middle::ty::inhabitedness::InhabitedPredicate,
|
||||||
rustc_middle::ty::Instance,
|
rustc_middle::ty::Instance,
|
||||||
rustc_middle::ty::InstanceKind,
|
rustc_middle::ty::InstanceKind,
|
||||||
|
|
|
@ -683,6 +683,24 @@ rustc_queries! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query const_conditions(
|
||||||
|
key: DefId
|
||||||
|
) -> ty::ConstConditions<'tcx> {
|
||||||
|
desc { |tcx| "computing the conditions for `{}` to be considered const",
|
||||||
|
tcx.def_path_str(key)
|
||||||
|
}
|
||||||
|
separate_provide_extern
|
||||||
|
}
|
||||||
|
|
||||||
|
query implied_const_bounds(
|
||||||
|
key: DefId
|
||||||
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||||
|
desc { |tcx| "computing the implied `~const` bounds for `{}`",
|
||||||
|
tcx.def_path_str(key)
|
||||||
|
}
|
||||||
|
separate_provide_extern
|
||||||
|
}
|
||||||
|
|
||||||
/// To avoid cycles within the predicates of a single item we compute
|
/// To avoid cycles within the predicates of a single item we compute
|
||||||
/// per-type-parameter predicates for resolving `T::AssocTy`.
|
/// per-type-parameter predicates for resolving `T::AssocTy`.
|
||||||
query type_param_predicates(
|
query type_param_predicates(
|
||||||
|
|
|
@ -386,6 +386,17 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for [(ty::Claus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
||||||
|
for [(ty::PolyTraitRef<'tcx>, Span)]
|
||||||
|
{
|
||||||
|
fn decode(decoder: &mut D) -> &'tcx Self {
|
||||||
|
decoder
|
||||||
|
.interner()
|
||||||
|
.arena
|
||||||
|
.alloc_from_iter((0..decoder.read_usize()).map(|_| Decodable::decode(decoder)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
||||||
for ty::List<ty::BoundVariableKind>
|
for ty::List<ty::BoundVariableKind>
|
||||||
{
|
{
|
||||||
|
|
|
@ -78,10 +78,10 @@ use crate::traits::solve::{
|
||||||
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
|
use crate::ty::predicate::ExistentialPredicateStableCmpExt as _;
|
||||||
use crate::ty::{
|
use crate::ty::{
|
||||||
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
|
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Clauses, Const, GenericArg, GenericArgs,
|
||||||
GenericArgsRef, GenericParamDefKind, ImplPolarity, List, ListWithCachedTypeInfo, ParamConst,
|
GenericArgsRef, GenericParamDefKind, HostPolarity, ImplPolarity, List, ListWithCachedTypeInfo,
|
||||||
ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate, PredicateKind,
|
ParamConst, ParamTy, Pattern, PatternKind, PolyExistentialPredicate, PolyFnSig, Predicate,
|
||||||
PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
|
PredicateKind, PredicatePolarity, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty,
|
||||||
Visibility,
|
TyKind, TyVid, Visibility,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[allow(rustc::usage_of_ty_tykind)]
|
#[allow(rustc::usage_of_ty_tykind)]
|
||||||
|
@ -383,6 +383,28 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||||
self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
|
self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_const_impl(self, def_id: DefId) -> bool {
|
||||||
|
self.constness(def_id) == hir::Constness::Const
|
||||||
|
}
|
||||||
|
|
||||||
|
fn const_conditions(
|
||||||
|
self,
|
||||||
|
def_id: DefId,
|
||||||
|
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
||||||
|
ty::EarlyBinder::bind(
|
||||||
|
self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn implied_const_bounds(
|
||||||
|
self,
|
||||||
|
def_id: DefId,
|
||||||
|
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
||||||
|
ty::EarlyBinder::bind(
|
||||||
|
self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn has_target_features(self, def_id: DefId) -> bool {
|
fn has_target_features(self, def_id: DefId) -> bool {
|
||||||
!self.codegen_fn_attrs(def_id).target_features.is_empty()
|
!self.codegen_fn_attrs(def_id).target_features.is_empty()
|
||||||
}
|
}
|
||||||
|
@ -2189,7 +2211,7 @@ macro_rules! nop_slice_lift {
|
||||||
nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>}
|
nop_slice_lift! {ty::ValTree<'a> => ty::ValTree<'tcx>}
|
||||||
|
|
||||||
TrivialLiftImpls! {
|
TrivialLiftImpls! {
|
||||||
ImplPolarity, PredicatePolarity, Promoted
|
ImplPolarity, PredicatePolarity, Promoted, HostPolarity,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! sty_debug_print {
|
macro_rules! sty_debug_print {
|
||||||
|
|
|
@ -265,6 +265,12 @@ impl FlagComputation {
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) => {
|
||||||
self.add_args(trait_pred.trait_ref.args);
|
self.add_args(trait_pred.trait_ref.args);
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(ty::HostEffectPredicate {
|
||||||
|
trait_ref,
|
||||||
|
host: _,
|
||||||
|
})) => {
|
||||||
|
self.add_args(trait_ref.args);
|
||||||
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
|
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(ty::OutlivesPredicate(
|
||||||
a,
|
a,
|
||||||
b,
|
b,
|
||||||
|
|
|
@ -422,3 +422,73 @@ impl<'tcx> GenericPredicates<'tcx> {
|
||||||
instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s));
|
instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `~const` bounds for a given item. This is represented using a struct much like
|
||||||
|
/// `GenericPredicates`, where you can either choose to only instantiate the "own"
|
||||||
|
/// bounds or all of the bounds including those from the parent. This distinction
|
||||||
|
/// is necessary for code like `compare_method_predicate_entailment`.
|
||||||
|
#[derive(Copy, Clone, Default, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||||
|
pub struct ConstConditions<'tcx> {
|
||||||
|
pub parent: Option<DefId>,
|
||||||
|
pub predicates: &'tcx [(ty::PolyTraitRef<'tcx>, Span)],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> ConstConditions<'tcx> {
|
||||||
|
pub fn instantiate(
|
||||||
|
self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
args: GenericArgsRef<'tcx>,
|
||||||
|
) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
|
||||||
|
let mut instantiated = vec![];
|
||||||
|
self.instantiate_into(tcx, &mut instantiated, args);
|
||||||
|
instantiated
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn instantiate_own(
|
||||||
|
self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
args: GenericArgsRef<'tcx>,
|
||||||
|
) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
|
||||||
|
{
|
||||||
|
EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn instantiate_own_identity(
|
||||||
|
self,
|
||||||
|
) -> impl Iterator<Item = (ty::PolyTraitRef<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
|
||||||
|
{
|
||||||
|
EarlyBinder::bind(self.predicates).iter_identity_copied()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(level = "debug", skip(self, tcx))]
|
||||||
|
fn instantiate_into(
|
||||||
|
self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>,
|
||||||
|
args: GenericArgsRef<'tcx>,
|
||||||
|
) {
|
||||||
|
if let Some(def_id) = self.parent {
|
||||||
|
tcx.const_conditions(def_id).instantiate_into(tcx, instantiated, args);
|
||||||
|
}
|
||||||
|
instantiated.extend(
|
||||||
|
self.predicates.iter().map(|&(p, s)| (EarlyBinder::bind(p).instantiate(tcx, args), s)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn instantiate_identity(self, tcx: TyCtxt<'tcx>) -> Vec<(ty::PolyTraitRef<'tcx>, Span)> {
|
||||||
|
let mut instantiated = vec![];
|
||||||
|
self.instantiate_identity_into(tcx, &mut instantiated);
|
||||||
|
instantiated
|
||||||
|
}
|
||||||
|
|
||||||
|
fn instantiate_identity_into(
|
||||||
|
self,
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
instantiated: &mut Vec<(ty::PolyTraitRef<'tcx>, Span)>,
|
||||||
|
) {
|
||||||
|
if let Some(def_id) = self.parent {
|
||||||
|
tcx.const_conditions(def_id).instantiate_identity_into(tcx, instantiated);
|
||||||
|
}
|
||||||
|
instantiated.extend(self.predicates.iter().copied());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -84,12 +84,13 @@ pub use self::parameterized::ParameterizedOverTcx;
|
||||||
pub use self::pattern::{Pattern, PatternKind};
|
pub use self::pattern::{Pattern, PatternKind};
|
||||||
pub use self::predicate::{
|
pub use self::predicate::{
|
||||||
AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
|
AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
|
||||||
ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo,
|
ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef,
|
||||||
OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection,
|
HostEffectPredicate, NormalizesTo, OutlivesPredicate, PolyCoercePredicate,
|
||||||
PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate,
|
PolyExistentialPredicate, PolyExistentialProjection, PolyExistentialTraitRef,
|
||||||
PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate,
|
PolyProjectionPredicate, PolyRegionOutlivesPredicate, PolySubtypePredicate, PolyTraitPredicate,
|
||||||
PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef,
|
PolyTraitRef, PolyTypeOutlivesPredicate, Predicate, PredicateKind, ProjectionPredicate,
|
||||||
TraitPredicate, TraitRef, TypeOutlivesPredicate,
|
RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef, TraitPredicate, TraitRef,
|
||||||
|
TypeOutlivesPredicate,
|
||||||
};
|
};
|
||||||
pub use self::region::BoundRegionKind::*;
|
pub use self::region::BoundRegionKind::*;
|
||||||
pub use self::region::{
|
pub use self::region::{
|
||||||
|
|
|
@ -132,6 +132,7 @@ parameterized_over_tcx! {
|
||||||
ty::Ty,
|
ty::Ty,
|
||||||
ty::FnSig,
|
ty::FnSig,
|
||||||
ty::GenericPredicates,
|
ty::GenericPredicates,
|
||||||
|
ty::ConstConditions,
|
||||||
ty::TraitRef,
|
ty::TraitRef,
|
||||||
ty::Const,
|
ty::Const,
|
||||||
ty::Predicate,
|
ty::Predicate,
|
||||||
|
|
|
@ -19,6 +19,7 @@ pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
|
||||||
pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
|
pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
|
||||||
pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>;
|
pub type ExistentialProjection<'tcx> = ir::ExistentialProjection<TyCtxt<'tcx>>;
|
||||||
pub type TraitPredicate<'tcx> = ir::TraitPredicate<TyCtxt<'tcx>>;
|
pub type TraitPredicate<'tcx> = ir::TraitPredicate<TyCtxt<'tcx>>;
|
||||||
|
pub type HostEffectPredicate<'tcx> = ir::HostEffectPredicate<TyCtxt<'tcx>>;
|
||||||
pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>;
|
pub type ClauseKind<'tcx> = ir::ClauseKind<TyCtxt<'tcx>>;
|
||||||
pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>;
|
pub type PredicateKind<'tcx> = ir::PredicateKind<TyCtxt<'tcx>>;
|
||||||
pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>;
|
pub type NormalizesTo<'tcx> = ir::NormalizesTo<TyCtxt<'tcx>>;
|
||||||
|
@ -143,6 +144,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
| PredicateKind::AliasRelate(..)
|
| PredicateKind::AliasRelate(..)
|
||||||
| PredicateKind::NormalizesTo(..) => false,
|
| PredicateKind::NormalizesTo(..) => false,
|
||||||
PredicateKind::Clause(ClauseKind::Trait(_))
|
PredicateKind::Clause(ClauseKind::Trait(_))
|
||||||
|
| PredicateKind::Clause(ClauseKind::HostEffect(..))
|
||||||
| PredicateKind::Clause(ClauseKind::RegionOutlives(_))
|
| PredicateKind::Clause(ClauseKind::RegionOutlives(_))
|
||||||
| PredicateKind::Clause(ClauseKind::TypeOutlives(_))
|
| PredicateKind::Clause(ClauseKind::TypeOutlives(_))
|
||||||
| PredicateKind::Clause(ClauseKind::Projection(_))
|
| PredicateKind::Clause(ClauseKind::Projection(_))
|
||||||
|
@ -644,6 +646,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
match predicate.skip_binder() {
|
match predicate.skip_binder() {
|
||||||
PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
|
PredicateKind::Clause(ClauseKind::Trait(t)) => Some(predicate.rebind(t)),
|
||||||
PredicateKind::Clause(ClauseKind::Projection(..))
|
PredicateKind::Clause(ClauseKind::Projection(..))
|
||||||
|
| PredicateKind::Clause(ClauseKind::HostEffect(..))
|
||||||
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
|
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
|
||||||
| PredicateKind::NormalizesTo(..)
|
| PredicateKind::NormalizesTo(..)
|
||||||
| PredicateKind::AliasRelate(..)
|
| PredicateKind::AliasRelate(..)
|
||||||
|
@ -664,6 +667,7 @@ impl<'tcx> Predicate<'tcx> {
|
||||||
match predicate.skip_binder() {
|
match predicate.skip_binder() {
|
||||||
PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
|
PredicateKind::Clause(ClauseKind::Projection(t)) => Some(predicate.rebind(t)),
|
||||||
PredicateKind::Clause(ClauseKind::Trait(..))
|
PredicateKind::Clause(ClauseKind::Trait(..))
|
||||||
|
| PredicateKind::Clause(ClauseKind::HostEffect(..))
|
||||||
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
|
| PredicateKind::Clause(ClauseKind::ConstArgHasType(..))
|
||||||
| PredicateKind::NormalizesTo(..)
|
| PredicateKind::NormalizesTo(..)
|
||||||
| PredicateKind::AliasRelate(..)
|
| PredicateKind::AliasRelate(..)
|
||||||
|
|
|
@ -3075,6 +3075,15 @@ define_print! {
|
||||||
p!(print(self.trait_ref.print_trait_sugared()))
|
p!(print(self.trait_ref.print_trait_sugared()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::HostEffectPredicate<'tcx> {
|
||||||
|
let constness = match self.host {
|
||||||
|
ty::HostPolarity::Const => { "const" }
|
||||||
|
ty::HostPolarity::Maybe => { "~const" }
|
||||||
|
};
|
||||||
|
p!(print(self.trait_ref.self_ty()), ": {constness} ");
|
||||||
|
p!(print(self.trait_ref.print_trait_sugared()))
|
||||||
|
}
|
||||||
|
|
||||||
ty::TypeAndMut<'tcx> {
|
ty::TypeAndMut<'tcx> {
|
||||||
p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
|
p!(write("{}", self.mutbl.prefix_str()), print(self.ty))
|
||||||
}
|
}
|
||||||
|
@ -3087,6 +3096,7 @@ define_print! {
|
||||||
ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
|
ty::ClauseKind::RegionOutlives(predicate) => p!(print(predicate)),
|
||||||
ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
|
ty::ClauseKind::TypeOutlives(predicate) => p!(print(predicate)),
|
||||||
ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
|
ty::ClauseKind::Projection(predicate) => p!(print(predicate)),
|
||||||
|
ty::ClauseKind::HostEffect(predicate) => p!(print(predicate)),
|
||||||
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
ty::ClauseKind::ConstArgHasType(ct, ty) => {
|
||||||
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
p!("the constant `", print(ct), "` has type `", print(ty), "`")
|
||||||
},
|
},
|
||||||
|
|
296
compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Normal file
296
compiler/rustc_next_trait_solver/src/solve/effect_goals.rs
Normal file
|
@ -0,0 +1,296 @@
|
||||||
|
//! Dealing with host effect goals, i.e. enforcing the constness in
|
||||||
|
//! `T: const Trait` or `T: ~const Trait`.
|
||||||
|
|
||||||
|
use rustc_type_ir::fast_reject::DeepRejectCtxt;
|
||||||
|
use rustc_type_ir::inherent::*;
|
||||||
|
use rustc_type_ir::{self as ty, Interner};
|
||||||
|
use tracing::instrument;
|
||||||
|
|
||||||
|
use super::assembly::Candidate;
|
||||||
|
use crate::delegate::SolverDelegate;
|
||||||
|
use crate::solve::assembly::{self};
|
||||||
|
use crate::solve::{
|
||||||
|
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, NoSolution,
|
||||||
|
QueryResult,
|
||||||
|
};
|
||||||
|
|
||||||
|
impl<D, I> assembly::GoalKind<D> for ty::HostEffectPredicate<I>
|
||||||
|
where
|
||||||
|
D: SolverDelegate<Interner = I>,
|
||||||
|
I: Interner,
|
||||||
|
{
|
||||||
|
fn self_ty(self) -> I::Ty {
|
||||||
|
self.self_ty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trait_ref(self, _: I) -> ty::TraitRef<I> {
|
||||||
|
self.trait_ref
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_self_ty(self, cx: I, self_ty: I::Ty) -> Self {
|
||||||
|
self.with_self_ty(cx, self_ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trait_def_id(self, _: I) -> I::DefId {
|
||||||
|
self.def_id()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn probe_and_match_goal_against_assumption(
|
||||||
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
source: rustc_type_ir::solve::CandidateSource<I>,
|
||||||
|
goal: Goal<I, Self>,
|
||||||
|
assumption: <I as Interner>::Clause,
|
||||||
|
then: impl FnOnce(&mut EvalCtxt<'_, D>) -> QueryResult<I>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
if let Some(host_clause) = assumption.as_host_effect_clause() {
|
||||||
|
if host_clause.def_id() == goal.predicate.def_id()
|
||||||
|
&& host_clause.host().satisfies(goal.predicate.host)
|
||||||
|
{
|
||||||
|
if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
|
||||||
|
goal.predicate.trait_ref.args,
|
||||||
|
host_clause.skip_binder().trait_ref.args,
|
||||||
|
) {
|
||||||
|
return Err(NoSolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecx.probe_trait_candidate(source).enter(|ecx| {
|
||||||
|
let assumption_trait_pred = ecx.instantiate_binder_with_infer(host_clause);
|
||||||
|
ecx.eq(
|
||||||
|
goal.param_env,
|
||||||
|
goal.predicate.trait_ref,
|
||||||
|
assumption_trait_pred.trait_ref,
|
||||||
|
)?;
|
||||||
|
then(ecx)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(NoSolution)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(NoSolution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_impl_candidate(
|
||||||
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
goal: Goal<I, Self>,
|
||||||
|
impl_def_id: <I as Interner>::DefId,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
let cx = ecx.cx();
|
||||||
|
|
||||||
|
let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
|
||||||
|
if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
|
||||||
|
.args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args)
|
||||||
|
{
|
||||||
|
return Err(NoSolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
let impl_polarity = cx.impl_polarity(impl_def_id);
|
||||||
|
match impl_polarity {
|
||||||
|
ty::ImplPolarity::Negative => return Err(NoSolution),
|
||||||
|
ty::ImplPolarity::Reservation => {
|
||||||
|
unimplemented!("reservation impl for const trait: {:?}", goal)
|
||||||
|
}
|
||||||
|
ty::ImplPolarity::Positive => {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if !cx.is_const_impl(impl_def_id) {
|
||||||
|
return Err(NoSolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
|
||||||
|
let impl_args = ecx.fresh_args_for_item(impl_def_id);
|
||||||
|
ecx.record_impl_args(impl_args);
|
||||||
|
let impl_trait_ref = impl_trait_ref.instantiate(cx, impl_args);
|
||||||
|
|
||||||
|
ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
|
||||||
|
let where_clause_bounds = cx
|
||||||
|
.predicates_of(impl_def_id)
|
||||||
|
.iter_instantiated(cx, impl_args)
|
||||||
|
.map(|pred| goal.with(cx, pred));
|
||||||
|
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
|
||||||
|
|
||||||
|
// For this impl to be `const`, we need to check its `~const` bounds too.
|
||||||
|
let const_conditions = cx
|
||||||
|
.const_conditions(impl_def_id)
|
||||||
|
.iter_instantiated(cx, impl_args)
|
||||||
|
.map(|bound_trait_ref| {
|
||||||
|
goal.with(cx, bound_trait_ref.to_host_effect_clause(cx, goal.predicate.host))
|
||||||
|
});
|
||||||
|
ecx.add_goals(GoalSource::ImplWhereBound, const_conditions);
|
||||||
|
|
||||||
|
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_error_guaranteed_candidate(
|
||||||
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_guar: <I as Interner>::ErrorGuaranteed,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc)
|
||||||
|
.enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_auto_trait_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("auto traits are never const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_trait_alias_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("trait aliases are never const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_sized_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("Sized is never const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_copy_clone_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
todo!("Copy/Clone is not yet const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_pointer_like_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("PointerLike is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_fn_ptr_trait_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
todo!("Fn* are not yet const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_fn_trait_candidates(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
_kind: rustc_type_ir::ClosureKind,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
todo!("Fn* are not yet const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_async_fn_trait_candidates(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
_kind: rustc_type_ir::ClosureKind,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
todo!("AsyncFn* are not yet const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_async_fn_kind_helper_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("AsyncFnKindHelper is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_tuple_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("Tuple trait is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_pointee_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("Pointee is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_future_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("Future is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_iterator_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
todo!("Iterator is not yet const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_fused_iterator_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("FusedIterator is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_async_iterator_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("AsyncIterator is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_coroutine_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("Coroutine is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_discriminant_kind_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("DiscriminantKind is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_async_destruct_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("AsyncDestruct is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_destruct_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("Destruct is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_builtin_transmute_candidate(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Result<Candidate<I>, NoSolution> {
|
||||||
|
unreachable!("TransmuteFrom is not const")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn consider_structural_builtin_unsize_candidates(
|
||||||
|
_ecx: &mut EvalCtxt<'_, D>,
|
||||||
|
_goal: Goal<I, Self>,
|
||||||
|
) -> Vec<Candidate<I>> {
|
||||||
|
unreachable!("Unsize is not const")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<D, I> EvalCtxt<'_, D>
|
||||||
|
where
|
||||||
|
D: SolverDelegate<Interner = I>,
|
||||||
|
I: Interner,
|
||||||
|
{
|
||||||
|
#[instrument(level = "trace", skip(self))]
|
||||||
|
pub(super) fn compute_host_effect_goal(
|
||||||
|
&mut self,
|
||||||
|
goal: Goal<I, ty::HostEffectPredicate<I>>,
|
||||||
|
) -> QueryResult<I> {
|
||||||
|
let candidates = self.assemble_and_evaluate_candidates(goal);
|
||||||
|
self.merge_candidates(candidates)
|
||||||
|
}
|
||||||
|
}
|
|
@ -443,6 +443,9 @@ where
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => {
|
||||||
self.compute_trait_goal(Goal { param_env, predicate })
|
self.compute_trait_goal(Goal { param_env, predicate })
|
||||||
}
|
}
|
||||||
|
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
|
||||||
|
self.compute_host_effect_goal(Goal { param_env, predicate })
|
||||||
|
}
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => {
|
||||||
self.compute_projection_goal(Goal { param_env, predicate })
|
self.compute_projection_goal(Goal { param_env, predicate })
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
mod alias_relate;
|
mod alias_relate;
|
||||||
mod assembly;
|
mod assembly;
|
||||||
|
mod effect_goals;
|
||||||
mod eval_ctxt;
|
mod eval_ctxt;
|
||||||
pub mod inspect;
|
pub mod inspect;
|
||||||
mod normalizes_to;
|
mod normalizes_to;
|
||||||
|
|
|
@ -137,6 +137,10 @@ where
|
||||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
|
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
|
||||||
self.visit_trait(trait_ref)
|
self.visit_trait(trait_ref)
|
||||||
}
|
}
|
||||||
|
ty::ClauseKind::HostEffect(pred) => {
|
||||||
|
try_visit!(self.visit_trait(pred.trait_ref));
|
||||||
|
pred.host.visit_with(self)
|
||||||
|
}
|
||||||
ty::ClauseKind::Projection(ty::ProjectionPredicate {
|
ty::ClauseKind::Projection(ty::ProjectionPredicate {
|
||||||
projection_term: projection_ty,
|
projection_term: projection_ty,
|
||||||
term,
|
term,
|
||||||
|
|
|
@ -689,6 +689,9 @@ impl<'tcx> Stable<'tcx> for ty::ClauseKind<'tcx> {
|
||||||
ClauseKind::ConstEvaluatable(const_) => {
|
ClauseKind::ConstEvaluatable(const_) => {
|
||||||
stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
|
stable_mir::ty::ClauseKind::ConstEvaluatable(const_.stable(tables))
|
||||||
}
|
}
|
||||||
|
ClauseKind::HostEffect(..) => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,8 +156,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
(leaf_trait_predicate, &obligation)
|
(leaf_trait_predicate, &obligation)
|
||||||
};
|
};
|
||||||
|
|
||||||
let (main_trait_predicate, leaf_trait_predicate, predicate_constness) = self.get_effects_trait_pred_override(main_trait_predicate, leaf_trait_predicate, span);
|
|
||||||
|
|
||||||
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
|
let main_trait_ref = main_trait_predicate.to_poly_trait_ref();
|
||||||
let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
|
let leaf_trait_ref = leaf_trait_predicate.to_poly_trait_ref();
|
||||||
|
|
||||||
|
@ -228,7 +226,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
let err_msg = self.get_standard_error_message(
|
let err_msg = self.get_standard_error_message(
|
||||||
main_trait_predicate,
|
main_trait_predicate,
|
||||||
message,
|
message,
|
||||||
predicate_constness,
|
None,
|
||||||
append_const_msg,
|
append_const_msg,
|
||||||
post_message,
|
post_message,
|
||||||
);
|
);
|
||||||
|
@ -289,13 +287,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if tcx.is_lang_item(leaf_trait_ref.def_id(), LangItem::Drop)
|
|
||||||
&& matches!(predicate_constness, Some(ty::BoundConstness::ConstIfConst | ty::BoundConstness::Const))
|
|
||||||
{
|
|
||||||
err.note("`~const Drop` was renamed to `~const Destruct`");
|
|
||||||
err.note("See <https://github.com/rust-lang/rust/pull/94901> for more details");
|
|
||||||
}
|
|
||||||
|
|
||||||
let explanation = get_explanation_based_on_obligation(
|
let explanation = get_explanation_based_on_obligation(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
&obligation,
|
&obligation,
|
||||||
|
@ -541,6 +532,29 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
err
|
err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(predicate)) => {
|
||||||
|
// FIXME(effects): We should recompute the predicate with `~const`
|
||||||
|
// if it's `const`, and if it holds, explain that this bound only
|
||||||
|
// *conditionally* holds. If that fails, we should also do selection
|
||||||
|
// to drill this down to an impl or built-in source, so we can
|
||||||
|
// point at it and explain that while the trait *is* implemented,
|
||||||
|
// that implementation is not const.
|
||||||
|
let err_msg = self.get_standard_error_message(
|
||||||
|
bound_predicate.rebind(ty::TraitPredicate {
|
||||||
|
trait_ref: predicate.trait_ref,
|
||||||
|
polarity: ty::PredicatePolarity::Positive,
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
Some(match predicate.host {
|
||||||
|
ty::HostPolarity::Maybe => ty::BoundConstness::ConstIfConst,
|
||||||
|
ty::HostPolarity::Const => ty::BoundConstness::Const,
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
String::new(),
|
||||||
|
);
|
||||||
|
struct_span_code_err!(self.dcx(), span, E0277, "{}", err_msg)
|
||||||
|
}
|
||||||
|
|
||||||
ty::PredicateKind::Subtype(predicate) => {
|
ty::PredicateKind::Subtype(predicate) => {
|
||||||
// Errors for Subtype predicates show up as
|
// Errors for Subtype predicates show up as
|
||||||
// `FulfillmentErrorCode::SubtypeError`,
|
// `FulfillmentErrorCode::SubtypeError`,
|
||||||
|
@ -2374,16 +2388,6 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(effects): Remove this.
|
|
||||||
fn get_effects_trait_pred_override(
|
|
||||||
&self,
|
|
||||||
p: ty::PolyTraitPredicate<'tcx>,
|
|
||||||
leaf: ty::PolyTraitPredicate<'tcx>,
|
|
||||||
_span: Span,
|
|
||||||
) -> (ty::PolyTraitPredicate<'tcx>, ty::PolyTraitPredicate<'tcx>, ty::BoundConstness) {
|
|
||||||
(p, leaf, ty::BoundConstness::NotConst)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_tuple_trait_message(
|
fn add_tuple_trait_message(
|
||||||
&self,
|
&self,
|
||||||
obligation_cause_code: &ObligationCauseCode<'tcx>,
|
obligation_cause_code: &ObligationCauseCode<'tcx>,
|
||||||
|
|
|
@ -806,7 +806,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
// FIXME(generic_const_exprs): you can absolutely add this as a where clauses
|
// FIXME(generic_const_exprs): you can absolutely add this as a where clauses
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::Coerce(..) => {}
|
| ty::PredicateKind::Coerce(..)
|
||||||
|
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {}
|
||||||
ty::PredicateKind::Ambiguous => return false,
|
ty::PredicateKind::Ambiguous => return false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,6 +245,7 @@ fn predicate_references_self<'tcx>(
|
||||||
| ty::ClauseKind::RegionOutlives(..)
|
| ty::ClauseKind::RegionOutlives(..)
|
||||||
// FIXME(generic_const_exprs): this can mention `Self`
|
// FIXME(generic_const_exprs): this can mention `Self`
|
||||||
| ty::ClauseKind::ConstEvaluatable(..)
|
| ty::ClauseKind::ConstEvaluatable(..)
|
||||||
|
| ty::ClauseKind::HostEffect(..)
|
||||||
=> None,
|
=> None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,7 +285,8 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
|
||||||
| ty::ClauseKind::Projection(_)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
| ty::ClauseKind::WellFormed(_)
|
| ty::ClauseKind::WellFormed(_)
|
||||||
| ty::ClauseKind::ConstEvaluatable(_) => false,
|
| ty::ClauseKind::ConstEvaluatable(_)
|
||||||
|
| ty::ClauseKind::HostEffect(..) => false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -372,7 +372,11 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
| ty::PredicateKind::Subtype(_)
|
| ty::PredicateKind::Subtype(_)
|
||||||
| ty::PredicateKind::Coerce(_)
|
| ty::PredicateKind::Coerce(_)
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
| ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
|
||||||
| ty::PredicateKind::ConstEquate(..) => {
|
| ty::PredicateKind::ConstEquate(..)
|
||||||
|
// FIXME(effects): We may need to do this using the higher-ranked
|
||||||
|
// pred instead of just instantiating it with placeholders b/c of
|
||||||
|
// higher-ranked implied bound issues in the old solver.
|
||||||
|
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||||
let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
|
let pred = ty::Binder::dummy(infcx.enter_forall_and_leak_universe(binder));
|
||||||
let mut obligations = PredicateObligations::with_capacity(1);
|
let mut obligations = PredicateObligations::with_capacity(1);
|
||||||
obligations.push(obligation.with(infcx.tcx, pred));
|
obligations.push(obligation.with(infcx.tcx, pred));
|
||||||
|
@ -398,6 +402,10 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||||
|
ProcessResult::Changed(Default::default())
|
||||||
|
}
|
||||||
|
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
|
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(data)) => {
|
||||||
if infcx.considering_regions {
|
if infcx.considering_regions {
|
||||||
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
|
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
|
||||||
|
|
|
@ -96,6 +96,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
|
||||||
// FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
|
// FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
|
||||||
// if we ever support that
|
// if we ever support that
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
||||||
|
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
|
@ -200,6 +201,7 @@ pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
|
||||||
// FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
|
// FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
|
||||||
// if we ever support that
|
// if we ever support that
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
||||||
|
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::Subtype(..)
|
| ty::PredicateKind::Subtype(..)
|
||||||
| ty::PredicateKind::Coerce(..)
|
| ty::PredicateKind::Coerce(..)
|
||||||
|
|
|
@ -645,6 +645,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
self.evaluate_trait_predicate_recursively(previous_stack, obligation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..)) => {
|
||||||
|
// FIXME(effects): It should be relatively straightforward to implement
|
||||||
|
// old trait solver support for `HostEffect` bounds; or at least basic
|
||||||
|
// support for them.
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
ty::PredicateKind::Subtype(p) => {
|
ty::PredicateKind::Subtype(p) => {
|
||||||
let p = bound_predicate.rebind(p);
|
let p = bound_predicate.rebind(p);
|
||||||
// Does this code ever run?
|
// Does this code ever run?
|
||||||
|
|
|
@ -170,6 +170,10 @@ pub fn clause_obligations<'tcx>(
|
||||||
ty::ClauseKind::Trait(t) => {
|
ty::ClauseKind::Trait(t) => {
|
||||||
wf.compute_trait_pred(t, Elaborate::None);
|
wf.compute_trait_pred(t, Elaborate::None);
|
||||||
}
|
}
|
||||||
|
ty::ClauseKind::HostEffect(..) => {
|
||||||
|
// Technically the well-formedness of this predicate is implied by
|
||||||
|
// the corresponding trait predicate it should've been generated beside.
|
||||||
|
}
|
||||||
ty::ClauseKind::RegionOutlives(..) => {}
|
ty::ClauseKind::RegionOutlives(..) => {}
|
||||||
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
|
||||||
wf.compute(ty.into());
|
wf.compute(ty.into());
|
||||||
|
@ -1021,6 +1025,7 @@ pub(crate) fn required_region_bounds<'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::ClauseKind::Trait(_)
|
ty::ClauseKind::Trait(_)
|
||||||
|
| ty::ClauseKind::HostEffect(..)
|
||||||
| ty::ClauseKind::RegionOutlives(_)
|
| ty::ClauseKind::RegionOutlives(_)
|
||||||
| ty::ClauseKind::Projection(_)
|
| ty::ClauseKind::Projection(_)
|
||||||
| ty::ClauseKind::ConstArgHasType(_, _)
|
| ty::ClauseKind::ConstArgHasType(_, _)
|
||||||
|
|
|
@ -55,6 +55,7 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool {
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) => false,
|
| ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(..)) => false,
|
||||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
|
| ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
|
||||||
|
| ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
|
||||||
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
| ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
|
||||||
| ty::PredicateKind::NormalizesTo(..)
|
| ty::PredicateKind::NormalizesTo(..)
|
||||||
| ty::PredicateKind::AliasRelate(..)
|
| ty::PredicateKind::AliasRelate(..)
|
||||||
|
|
|
@ -150,6 +150,15 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We extend the param-env of our item with the const conditions of the item,
|
||||||
|
// since we're allowed to assume `~const` bounds hold within the item itself.
|
||||||
|
predicates.extend(
|
||||||
|
tcx.const_conditions(def_id)
|
||||||
|
.instantiate_identity(tcx)
|
||||||
|
.into_iter()
|
||||||
|
.map(|(trait_ref, _)| trait_ref.to_host_effect_clause(tcx, ty::HostPolarity::Maybe)),
|
||||||
|
);
|
||||||
|
|
||||||
let local_did = def_id.as_local();
|
let local_did = def_id.as_local();
|
||||||
|
|
||||||
let unnormalized_env =
|
let unnormalized_env =
|
||||||
|
|
|
@ -155,6 +155,16 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
// `T: ~const Trait` implies `T: ~const Supertrait`.
|
||||||
|
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
|
||||||
|
cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
|
||||||
|
elaboratable.child(
|
||||||
|
trait_ref
|
||||||
|
.to_host_effect_clause(cx, data.host)
|
||||||
|
.instantiate_supertrait(cx, bound_clause.rebind(data.trait_ref)),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
),
|
||||||
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
|
ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
|
||||||
// We know that `T: 'a` for some type `T`. We can
|
// We know that `T: 'a` for some type `T`. We can
|
||||||
// often elaborate this. For example, if we know that
|
// often elaborate this. For example, if we know that
|
||||||
|
|
|
@ -468,6 +468,14 @@ pub trait Clause<I: Interner<Clause = Self>>:
|
||||||
.transpose()
|
.transpose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_host_effect_clause(self) -> Option<ty::Binder<I, ty::HostEffectPredicate<I>>> {
|
||||||
|
self.kind()
|
||||||
|
.map_bound(
|
||||||
|
|clause| if let ty::ClauseKind::HostEffect(t) = clause { Some(t) } else { None },
|
||||||
|
)
|
||||||
|
.transpose()
|
||||||
|
}
|
||||||
|
|
||||||
fn as_projection_clause(self) -> Option<ty::Binder<I, ty::ProjectionPredicate<I>>> {
|
fn as_projection_clause(self) -> Option<ty::Binder<I, ty::ProjectionPredicate<I>>> {
|
||||||
self.kind()
|
self.kind()
|
||||||
.map_bound(
|
.map_bound(
|
||||||
|
|
|
@ -24,6 +24,7 @@ pub trait Interner:
|
||||||
+ IrPrint<ty::AliasTerm<Self>>
|
+ IrPrint<ty::AliasTerm<Self>>
|
||||||
+ IrPrint<ty::TraitRef<Self>>
|
+ IrPrint<ty::TraitRef<Self>>
|
||||||
+ IrPrint<ty::TraitPredicate<Self>>
|
+ IrPrint<ty::TraitPredicate<Self>>
|
||||||
|
+ IrPrint<ty::HostEffectPredicate<Self>>
|
||||||
+ IrPrint<ty::ExistentialTraitRef<Self>>
|
+ IrPrint<ty::ExistentialTraitRef<Self>>
|
||||||
+ IrPrint<ty::ExistentialProjection<Self>>
|
+ IrPrint<ty::ExistentialProjection<Self>>
|
||||||
+ IrPrint<ty::ProjectionPredicate<Self>>
|
+ IrPrint<ty::ProjectionPredicate<Self>>
|
||||||
|
@ -228,6 +229,16 @@ pub trait Interner:
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = (Self::Clause, Self::Span)>>;
|
||||||
|
|
||||||
|
fn is_const_impl(self, def_id: Self::DefId) -> bool;
|
||||||
|
fn const_conditions(
|
||||||
|
self,
|
||||||
|
def_id: Self::DefId,
|
||||||
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||||
|
fn implied_const_bounds(
|
||||||
|
self,
|
||||||
|
def_id: Self::DefId,
|
||||||
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||||
|
|
||||||
fn has_target_features(self, def_id: Self::DefId) -> bool;
|
fn has_target_features(self, def_id: Self::DefId) -> bool;
|
||||||
|
|
||||||
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId;
|
fn require_lang_item(self, lang_item: TraitSolverLangItem) -> Self::DefId;
|
||||||
|
|
|
@ -2,8 +2,8 @@ use std::fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AliasTerm, AliasTy, Binder, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
|
AliasTerm, AliasTy, Binder, CoercePredicate, ExistentialProjection, ExistentialTraitRef, FnSig,
|
||||||
Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate, SubtypePredicate,
|
HostEffectPredicate, Interner, NormalizesTo, OutlivesPredicate, ProjectionPredicate,
|
||||||
TraitPredicate, TraitRef,
|
SubtypePredicate, TraitPredicate, TraitRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait IrPrint<T> {
|
pub trait IrPrint<T> {
|
||||||
|
@ -53,6 +53,7 @@ define_display_via_print!(
|
||||||
NormalizesTo,
|
NormalizesTo,
|
||||||
SubtypePredicate,
|
SubtypePredicate,
|
||||||
CoercePredicate,
|
CoercePredicate,
|
||||||
|
HostEffectPredicate,
|
||||||
AliasTy,
|
AliasTy,
|
||||||
AliasTerm,
|
AliasTerm,
|
||||||
FnSig,
|
FnSig,
|
||||||
|
|
|
@ -111,6 +111,13 @@ impl<I: Interner> ty::Binder<I, TraitRef<I>> {
|
||||||
pub fn def_id(&self) -> I::DefId {
|
pub fn def_id(&self) -> I::DefId {
|
||||||
self.skip_binder().def_id
|
self.skip_binder().def_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_host_effect_clause(self, cx: I, host: HostPolarity) -> I::Clause {
|
||||||
|
self.map_bound(|trait_ref| {
|
||||||
|
ty::ClauseKind::HostEffect(HostEffectPredicate { trait_ref, host })
|
||||||
|
})
|
||||||
|
.upcast(cx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||||
|
@ -745,6 +752,64 @@ impl<I: Interner> fmt::Debug for NormalizesTo<I> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
|
||||||
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||||
|
pub struct HostEffectPredicate<I: Interner> {
|
||||||
|
pub trait_ref: ty::TraitRef<I>,
|
||||||
|
pub host: HostPolarity,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> HostEffectPredicate<I> {
|
||||||
|
pub fn self_ty(self) -> I::Ty {
|
||||||
|
self.trait_ref.self_ty()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
|
||||||
|
Self { trait_ref: self.trait_ref.with_self_ty(interner, self_ty), ..self }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn def_id(self) -> I::DefId {
|
||||||
|
self.trait_ref.def_id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> ty::Binder<I, HostEffectPredicate<I>> {
|
||||||
|
pub fn def_id(self) -> I::DefId {
|
||||||
|
// Ok to skip binder since trait `DefId` does not care about regions.
|
||||||
|
self.skip_binder().def_id()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn self_ty(self) -> ty::Binder<I, I::Ty> {
|
||||||
|
self.map_bound(|trait_ref| trait_ref.self_ty())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn host(self) -> HostPolarity {
|
||||||
|
self.skip_binder().host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Hash, PartialEq, Eq, Debug)]
|
||||||
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
|
||||||
|
pub enum HostPolarity {
|
||||||
|
/// May be called in const environments if the callee is const.
|
||||||
|
Maybe,
|
||||||
|
/// Always allowed to be called in const environments.
|
||||||
|
Const,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HostPolarity {
|
||||||
|
pub fn satisfies(self, goal: HostPolarity) -> bool {
|
||||||
|
match (self, goal) {
|
||||||
|
(HostPolarity::Const, HostPolarity::Const | HostPolarity::Maybe) => true,
|
||||||
|
(HostPolarity::Maybe, HostPolarity::Maybe) => true,
|
||||||
|
(HostPolarity::Maybe, HostPolarity::Const) => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
|
/// Encodes that `a` must be a subtype of `b`. The `a_is_expected` flag indicates
|
||||||
/// whether the `a` type is the type that we should label as "expected" when
|
/// whether the `a` type is the type that we should label as "expected" when
|
||||||
/// presenting user diagnostics.
|
/// presenting user diagnostics.
|
||||||
|
|
|
@ -37,6 +37,12 @@ pub enum ClauseKind<I: Interner> {
|
||||||
|
|
||||||
/// Constant initializer must evaluate successfully.
|
/// Constant initializer must evaluate successfully.
|
||||||
ConstEvaluatable(I::Const),
|
ConstEvaluatable(I::Const),
|
||||||
|
|
||||||
|
/// Enforces the constness of the predicate we're calling. Like a projection
|
||||||
|
/// goal from a where clause, it's always going to be paired with a
|
||||||
|
/// corresponding trait clause; this just enforces the *constness* of that
|
||||||
|
/// implementation.
|
||||||
|
HostEffect(ty::HostEffectPredicate<I>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
#[derive_where(Clone, Copy, Hash, PartialEq, Eq; I: Interner)]
|
||||||
|
@ -110,6 +116,7 @@ impl<I: Interner> fmt::Debug for ClauseKind<I> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"),
|
ClauseKind::ConstArgHasType(ct, ty) => write!(f, "ConstArgHasType({ct:?}, {ty:?})"),
|
||||||
|
ClauseKind::HostEffect(data) => data.fmt(f),
|
||||||
ClauseKind::Trait(a) => a.fmt(f),
|
ClauseKind::Trait(a) => a.fmt(f),
|
||||||
ClauseKind::RegionOutlives(pair) => pair.fmt(f),
|
ClauseKind::RegionOutlives(pair) => pair.fmt(f),
|
||||||
ClauseKind::TypeOutlives(pair) => pair.fmt(f),
|
ClauseKind::TypeOutlives(pair) => pair.fmt(f),
|
||||||
|
|
|
@ -368,7 +368,9 @@ pub(crate) fn clean_predicate<'tcx>(
|
||||||
// FIXME(generic_const_exprs): should this do something?
|
// FIXME(generic_const_exprs): should this do something?
|
||||||
ty::ClauseKind::ConstEvaluatable(..)
|
ty::ClauseKind::ConstEvaluatable(..)
|
||||||
| ty::ClauseKind::WellFormed(..)
|
| ty::ClauseKind::WellFormed(..)
|
||||||
| ty::ClauseKind::ConstArgHasType(..) => None,
|
| ty::ClauseKind::ConstArgHasType(..)
|
||||||
|
// FIXME(effects): We can probably use this `HostEffect` pred to render `~const`.
|
||||||
|
| ty::ClauseKind::HostEffect(_) => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
//@ known-bug: #118320
|
|
||||||
//@ edition:2021
|
|
||||||
#![feature(const_trait_impl, effects, const_closures)]
|
|
||||||
|
|
||||||
#[const_trait]
|
|
||||||
trait Bar {
|
|
||||||
fn foo(&self);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Bar for () {}
|
|
||||||
|
|
||||||
const FOO: () = {
|
|
||||||
(const || (()).foo())();
|
|
||||||
};
|
|
|
@ -1,15 +0,0 @@
|
||||||
//@ known-bug: #119924
|
|
||||||
//@ compile-flags: -Znext-solver
|
|
||||||
#![feature(const_trait_impl, effects)]
|
|
||||||
|
|
||||||
struct S;
|
|
||||||
#[const_trait]
|
|
||||||
trait Trait<const N: u32> {}
|
|
||||||
|
|
||||||
const fn f<T: Trait<{
|
|
||||||
struct I<U: ~const Trait<0>>(U); // should've gotten rejected during AST validation
|
|
||||||
//~^ ICE no host param id for call in const yet no errors reported
|
|
||||||
0
|
|
||||||
}>>() {}
|
|
||||||
|
|
||||||
pub fn main() {}
|
|
|
@ -11,30 +11,12 @@ error[E0284]: type annotations needed: cannot normalize `<&T as ConstName>::{con
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
||||||
| ^^ cannot normalize `<&T as ConstName>::{constant#0}`
|
| ^^ cannot normalize `<&T as ConstName>::{constant#0}`
|
||||||
|
|
|
||||||
note: required for `&T` to implement `ConstName`
|
|
||||||
--> $DIR/issue-88119.rs:19:35
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + ConstName> const ConstName for &T
|
|
||||||
| ^^^^^^^^^ ^^
|
|
||||||
LL | where
|
|
||||||
LL | [(); name_len::<T>()]:,
|
|
||||||
| --------------------- unsatisfied trait bound introduced here
|
|
||||||
|
|
||||||
error[E0284]: type annotations needed: cannot normalize `<&mut T as ConstName>::{constant#0}`
|
error[E0284]: type annotations needed: cannot normalize `<&mut T as ConstName>::{constant#0}`
|
||||||
--> $DIR/issue-88119.rs:26:49
|
--> $DIR/issue-88119.rs:26:49
|
||||||
|
|
|
|
||||||
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
||||||
| ^^^^^^ cannot normalize `<&mut T as ConstName>::{constant#0}`
|
| ^^^^^^ cannot normalize `<&mut T as ConstName>::{constant#0}`
|
||||||
|
|
|
||||||
note: required for `&mut T` to implement `ConstName`
|
|
||||||
--> $DIR/issue-88119.rs:26:35
|
|
||||||
|
|
|
||||||
LL | impl<T: ?Sized + ConstName> const ConstName for &mut T
|
|
||||||
| ^^^^^^^^^ ^^^^^^
|
|
||||||
LL | where
|
|
||||||
LL | [(); name_len::<T>()]:,
|
|
||||||
| --------------------- unsatisfied trait bound introduced here
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn f<T: ~const Destruct>(x: T) {}
|
LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-block-const-bound.rs:8:22
|
||||||
|
|
|
||||||
|
LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-block-const-bound.rs:8:32
|
--> $DIR/const-block-const-bound.rs:8:32
|
||||||
|
|
|
|
||||||
|
@ -12,6 +20,6 @@ LL | const fn f<T: ~const Destruct>(x: T) {}
|
||||||
| |
|
| |
|
||||||
| the destructor for this type cannot be evaluated in constant functions
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0493`.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -3,24 +3,12 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||||
= help: use `-Znext-solver` to enable
|
= help: use `-Znext-solver` to enable
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
|
||||||
--> $DIR/constifconst-call-in-const-position.rs:17:38
|
--> $DIR/constifconst-call-in-const-position.rs:17:38
|
||||||
|
|
|
|
||||||
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
|
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
|
||||||
| ^^^^^^ expected `false`, found `host`
|
| ^^^^^^ calling non-const function `<() as Tr>::a`
|
||||||
|
|
|
||||||
= note: expected constant `false`
|
|
||||||
found constant `host`
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error: aborting due to 2 previous errors
|
||||||
--> $DIR/constifconst-call-in-const-position.rs:18:9
|
|
||||||
|
|
|
||||||
LL | [0; T::a()]
|
|
||||||
| ^^^^^^ expected `false`, found `host`
|
|
||||||
|
|
|
||||||
= note: expected constant `false`
|
|
||||||
found constant `host`
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
For more information about this error, try `rustc --explain E0080`.
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
|
|
@ -30,6 +30,22 @@ LL | T: ~const Fn<()> + ~const Destruct,
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:13:15
|
||||||
|
|
|
||||||
|
LL | T: ~const Fn<()> + ~const Destruct,
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:13:31
|
||||||
|
|
|
||||||
|
LL | T: ~const Fn<()> + ~const Destruct,
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/fn_trait_refs.rs:20:15
|
--> $DIR/fn_trait_refs.rs:20:15
|
||||||
|
|
|
|
||||||
|
@ -50,6 +66,22 @@ LL | T: ~const FnMut<()> + ~const Destruct,
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:20:15
|
||||||
|
|
|
||||||
|
LL | T: ~const FnMut<()> + ~const Destruct,
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:20:34
|
||||||
|
|
|
||||||
|
LL | T: ~const FnMut<()> + ~const Destruct,
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/fn_trait_refs.rs:27:15
|
--> $DIR/fn_trait_refs.rs:27:15
|
||||||
|
|
|
|
||||||
|
@ -64,6 +96,14 @@ LL | T: ~const FnOnce<()>,
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:27:15
|
||||||
|
|
|
||||||
|
LL | T: ~const FnOnce<()>,
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/fn_trait_refs.rs:34:15
|
--> $DIR/fn_trait_refs.rs:34:15
|
||||||
|
|
|
|
||||||
|
@ -84,6 +124,22 @@ LL | T: ~const Fn<()> + ~const Destruct,
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:34:15
|
||||||
|
|
|
||||||
|
LL | T: ~const Fn<()> + ~const Destruct,
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:34:31
|
||||||
|
|
|
||||||
|
LL | T: ~const Fn<()> + ~const Destruct,
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/fn_trait_refs.rs:48:15
|
--> $DIR/fn_trait_refs.rs:48:15
|
||||||
|
|
|
|
||||||
|
@ -104,6 +160,22 @@ LL | T: ~const FnMut<()> + ~const Destruct,
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:48:15
|
||||||
|
|
|
||||||
|
LL | T: ~const FnMut<()> + ~const Destruct,
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/fn_trait_refs.rs:48:34
|
||||||
|
|
|
||||||
|
LL | T: ~const FnMut<()> + ~const Destruct,
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constants
|
error[E0015]: cannot call non-const operator in constants
|
||||||
--> $DIR/fn_trait_refs.rs:70:17
|
--> $DIR/fn_trait_refs.rs:70:17
|
||||||
|
|
|
|
||||||
|
@ -212,7 +284,7 @@ LL | const fn test_fn_mut<T>(mut f: T) -> (T::Output, T::Output)
|
||||||
LL | }
|
LL | }
|
||||||
| - value is dropped here
|
| - value is dropped here
|
||||||
|
|
||||||
error: aborting due to 25 previous errors
|
error: aborting due to 34 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0493, E0635.
|
Some errors have detailed explanations: E0015, E0493, E0635.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/unstable-const-fn-in-libcore.rs:19:39
|
||||||
|
|
|
||||||
|
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error[E0015]: cannot call non-const closure in constant functions
|
||||||
--> $DIR/unstable-const-fn-in-libcore.rs:24:26
|
--> $DIR/unstable-const-fn-in-libcore.rs:24:26
|
||||||
|
|
|
|
||||||
|
@ -38,7 +46,7 @@ LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
||||||
LL | }
|
LL | }
|
||||||
| - value is dropped here
|
| - value is dropped here
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0493.
|
Some errors have detailed explanations: E0015, E0493.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
// FIXME(fn_delegation): `recursive delegation` error should be emitted here
|
// FIXME(fn_delegation): `recursive delegation` error should be emitted here
|
||||||
trait Trait {
|
trait Trait {
|
||||||
reuse Trait::foo { &self.0 }
|
reuse Trait::foo { &self.0 }
|
||||||
//~^ ERROR cycle detected when computing generics of `Trait::foo`
|
//~^ ERROR recursive delegation is not supported yet
|
||||||
}
|
}
|
||||||
|
|
||||||
reuse foo;
|
reuse foo;
|
||||||
|
|
|
@ -1,16 +1,8 @@
|
||||||
error[E0391]: cycle detected when computing generics of `Trait::foo`
|
error: recursive delegation is not supported yet
|
||||||
--> $DIR/ice-issue-124347.rs:6:18
|
--> $DIR/ice-issue-124347.rs:6:18
|
||||||
|
|
|
|
||||||
LL | reuse Trait::foo { &self.0 }
|
LL | reuse Trait::foo { &self.0 }
|
||||||
| ^^^
|
| ^^^ callee defined here
|
||||||
|
|
|
||||||
= note: ...which immediately requires computing generics of `Trait::foo` again
|
|
||||||
note: cycle used when inheriting delegation signature
|
|
||||||
--> $DIR/ice-issue-124347.rs:6:18
|
|
||||||
|
|
|
||||||
LL | reuse Trait::foo { &self.0 }
|
|
||||||
| ^^^
|
|
||||||
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
|
|
||||||
|
|
||||||
error[E0391]: cycle detected when computing generics of `foo`
|
error[E0391]: cycle detected when computing generics of `foo`
|
||||||
--> $DIR/ice-issue-124347.rs:10:7
|
--> $DIR/ice-issue-124347.rs:10:7
|
||||||
|
|
|
@ -51,7 +51,7 @@ mod effects {
|
||||||
}
|
}
|
||||||
|
|
||||||
reuse Trait::foo;
|
reuse Trait::foo;
|
||||||
//~^ ERROR delegation to a function with effect parameter is not supported yet
|
//~^ ERROR type annotations needed
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -81,15 +81,15 @@ LL | pub reuse to_reuse2::foo;
|
||||||
LL | reuse to_reuse1::foo;
|
LL | reuse to_reuse1::foo;
|
||||||
| ^^^
|
| ^^^
|
||||||
|
|
||||||
error: delegation to a function with effect parameter is not supported yet
|
error[E0283]: type annotations needed
|
||||||
--> $DIR/unsupported.rs:53:18
|
--> $DIR/unsupported.rs:53:18
|
||||||
|
|
|
|
||||||
LL | fn foo();
|
|
||||||
| --------- callee defined here
|
|
||||||
...
|
|
||||||
LL | reuse Trait::foo;
|
LL | reuse Trait::foo;
|
||||||
| ^^^
|
| ^^^ cannot infer type
|
||||||
|
|
|
||||||
|
= note: cannot satisfy `_: effects::Trait`
|
||||||
|
|
||||||
error: aborting due to 5 previous errors; 2 warnings emitted
|
error: aborting due to 5 previous errors; 2 warnings emitted
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0391`.
|
Some errors have detailed explanations: E0283, E0391.
|
||||||
|
For more information about an error, try `rustc --explain E0283`.
|
||||||
|
|
|
@ -10,6 +10,22 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/normalize-tait-in-const.rs:26:42
|
||||||
|
|
|
||||||
|
LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/normalize-tait-in-const.rs:26:69
|
||||||
|
|
|
||||||
|
LL | const fn with_positive<F: for<'a> ~const Fn(&'a Alias<'a>) + ~const Destruct>(fun: F) {
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error[E0015]: cannot call non-const closure in constant functions
|
||||||
--> $DIR/normalize-tait-in-const.rs:27:5
|
--> $DIR/normalize-tait-in-const.rs:27:5
|
||||||
|
|
|
|
||||||
|
@ -35,7 +51,7 @@ LL | fun(filter_positive());
|
||||||
LL | }
|
LL | }
|
||||||
| - value is dropped here
|
| - value is dropped here
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0493.
|
Some errors have detailed explanations: E0015, E0493.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,23 +1,3 @@
|
||||||
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
|
|
||||||
--> $DIR/const_trait_impl.rs:6:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
|
||||||
LL | pub unsafe trait Sup {
|
|
||||||
LL | fn foo() -> u32;
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
|
|
||||||
--> $DIR/const_trait_impl.rs:6:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
|
||||||
LL | pub unsafe trait Sup {
|
|
||||||
LL | fn foo() -> u32;
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const_trait_impl.rs:34:16
|
--> $DIR/const_trait_impl.rs:34:16
|
||||||
|
|
|
|
||||||
|
@ -36,34 +16,27 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | impl<T: ~const Default + ~const Sub> const A for T {
|
LL | impl<T: ~const Default + ~const Sub> const A for T {
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const_trait_impl.rs:29:1
|
--> $DIR/const_trait_impl.rs:40:16
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | impl<T: ~const Default + ~const Sup> const A for T {
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^
|
||||||
LL | pub trait A {
|
|
||||||
LL | fn a() -> u32;
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
|
|
||||||
--> $DIR/const_trait_impl.rs:29:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
|
||||||
LL | pub trait A {
|
|
||||||
LL | fn a() -> u32;
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0049]: associated function `a` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const_trait_impl.rs:29:1
|
--> $DIR/const_trait_impl.rs:34:16
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | impl<T: ~const Default> const A for T {
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^
|
||||||
LL | pub trait A {
|
|
|
||||||
LL | fn a() -> u32;
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
| - expected 0 const parameters
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const_trait_impl.rs:46:16
|
||||||
|
|
|
||||||
|
LL | impl<T: ~const Default + ~const Sub> const A for T {
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
@ -115,7 +88,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||||
LL + #![feature(effects)]
|
LL + #![feature(effects)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 12 previous errors
|
error: aborting due to 10 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -3,44 +3,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||||
= help: use `-Znext-solver` to enable
|
= help: use `-Znext-solver` to enable
|
||||||
|
|
||||||
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/assoc-type-const-bound-usage-0.rs:13:5
|
|
||||||
|
|
|
||||||
LL | T::Assoc::func()
|
|
||||||
| ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Trait::func`
|
|
||||||
--> $DIR/assoc-type-const-bound-usage-0.rs:6:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
|
|
||||||
...
|
|
||||||
LL | fn func() -> i32;
|
|
||||||
| ---- required by a bound in this associated function
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | const fn unqualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
|
|
||||||
| ++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
|
|
||||||
--> $DIR/assoc-type-const-bound-usage-0.rs:17:5
|
|
||||||
|
|
|
||||||
LL | <T as Trait>::Assoc::func()
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Trait::func`
|
|
||||||
--> $DIR/assoc-type-const-bound-usage-0.rs:6:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
|
|
||||||
...
|
|
||||||
LL | fn func() -> i32;
|
|
||||||
| ---- required by a bound in this associated function
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | const fn qualified<T: ~const Trait>() -> i32 where <T as Trait>::Assoc: Trait {
|
|
||||||
| ++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -3,44 +3,5 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
||||||
= help: use `-Znext-solver` to enable
|
= help: use `-Znext-solver` to enable
|
||||||
|
|
||||||
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
|
error: aborting due to 1 previous error
|
||||||
--> $DIR/assoc-type-const-bound-usage-1.rs:15:44
|
|
||||||
|
|
|
||||||
LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> {
|
|
||||||
| ^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Trait::func`
|
|
||||||
--> $DIR/assoc-type-const-bound-usage-1.rs:7:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
|
|
||||||
...
|
|
||||||
LL | fn func() -> i32;
|
|
||||||
| ---- required by a bound in this associated function
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | fn unqualified<T: const Trait>() -> Type<{ T::Assoc::func() }> where <T as Trait>::Assoc: Trait {
|
|
||||||
| ++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error[E0277]: the trait bound `<T as Trait>::Assoc: Trait` is not satisfied
|
|
||||||
--> $DIR/assoc-type-const-bound-usage-1.rs:19:42
|
|
||||||
|
|
|
||||||
LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `<T as Trait>::Assoc`
|
|
||||||
|
|
|
||||||
note: required by a bound in `Trait::func`
|
|
||||||
--> $DIR/assoc-type-const-bound-usage-1.rs:7:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `Trait::func`
|
|
||||||
...
|
|
||||||
LL | fn func() -> i32;
|
|
||||||
| ---- required by a bound in this associated function
|
|
||||||
help: consider further restricting the associated type
|
|
||||||
|
|
|
||||||
LL | fn qualified<T: const Trait>() -> Type<{ <T as Trait>::Assoc::func() }> where <T as Trait>::Assoc: Trait {
|
|
||||||
| ++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
||||||
|
|
|
@ -2,20 +2,7 @@ error[E0277]: the trait bound `u32: ~const Plus` is not satisfied
|
||||||
--> $DIR/call-const-trait-method-fail.rs:27:5
|
--> $DIR/call-const-trait-method-fail.rs:27:5
|
||||||
|
|
|
|
||||||
LL | a.plus(b)
|
LL | a.plus(b)
|
||||||
| ^ the trait `Plus` is not implemented for `u32`
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
note: required by a bound in `Plus::plus`
|
|
||||||
--> $DIR/call-const-trait-method-fail.rs:5:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `Plus::plus`
|
|
||||||
LL | pub trait Plus {
|
|
||||||
LL | fn plus(self, rhs: Self) -> Self;
|
|
||||||
| ---- required by a bound in this associated function
|
|
||||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
|
||||||
|
|
|
||||||
LL | pub const fn add_u32(a: u32, b: u32) -> u32 where u32: Plus {
|
|
||||||
| +++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -16,15 +16,6 @@ LL | impl const PartialEq for Int {
|
||||||
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
|
= note: marking a trait with `#[const_trait]` ensures all default method bodies are `const`
|
||||||
= note: adding a non-const method body in the future would be a breaking change
|
= note: adding a non-const method body in the future would be a breaking change
|
||||||
|
|
||||||
error[E0049]: method `plus` has 1 const parameter but its trait declaration has 0 const parameters
|
|
||||||
--> $DIR/call-const-trait-method-pass.rs:24:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
|
||||||
LL | pub trait Plus {
|
|
||||||
LL | fn plus(self, rhs: Self) -> Self;
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constants
|
error[E0015]: cannot call non-const operator in constants
|
||||||
--> $DIR/call-const-trait-method-pass.rs:39:22
|
--> $DIR/call-const-trait-method-pass.rs:39:22
|
||||||
|
|
|
|
||||||
|
@ -73,7 +64,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||||
LL + #![feature(effects)]
|
LL + #![feature(effects)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | impl<T: ~const PartialEq> const MyPartialEq for T {
|
LL | impl<T: ~const PartialEq> const MyPartialEq for T {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error[E0049]: method `eq` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/call-generic-in-impl.rs:5:1
|
--> $DIR/call-generic-in-impl.rs:10:16
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | impl<T: ~const PartialEq> const MyPartialEq for T {
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^^^
|
||||||
LL | trait MyPartialEq {
|
|
|
||||||
LL | fn eq(&self, other: &Self) -> bool;
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const fn `<T as PartialEq>::eq` in constant functions
|
error[E0015]: cannot call non-const fn `<T as PartialEq>::eq` in constant functions
|
||||||
--> $DIR/call-generic-in-impl.rs:12:9
|
--> $DIR/call-generic-in-impl.rs:12:9
|
||||||
|
@ -27,5 +26,4 @@ LL + #![feature(effects)]
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -27,11 +27,27 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/call-generic-method-chain.rs:19:32
|
||||||
|
|
|
||||||
|
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/call-generic-method-chain.rs:23:40
|
--> $DIR/call-generic-method-chain.rs:23:40
|
||||||
|
|
|
|
||||||
LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
|
LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors; 1 warning emitted
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/call-generic-method-chain.rs:23:40
|
||||||
|
|
|
||||||
|
LL | const fn equals_self_wrapper<T: ~const PartialEq>(t: &T) -> bool {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,27 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
|
LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/call-generic-method-dup-bound.rs:19:44
|
||||||
|
|
|
||||||
|
LL | const fn equals_self<T: PartialEq + ~const PartialEq>(t: &T) -> bool {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/call-generic-method-dup-bound.rs:26:37
|
--> $DIR/call-generic-method-dup-bound.rs:26:37
|
||||||
|
|
|
|
||||||
LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
|
LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 4 previous errors; 1 warning emitted
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/call-generic-method-dup-bound.rs:26:37
|
||||||
|
|
|
||||||
|
LL | const fn equals_self2<T: A + ~const PartialEq>(t: &T) -> bool {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,8 @@
|
||||||
error[E0277]: the trait bound `S: const Foo` is not satisfied
|
error[E0277]: the trait bound `S: const Foo` is not satisfied
|
||||||
--> $DIR/call-generic-method-nonconst.rs:25:34
|
--> $DIR/call-generic-method-nonconst.rs:25:22
|
||||||
|
|
|
|
||||||
LL | pub const EQ: bool = equals_self(&S);
|
LL | pub const EQ: bool = equals_self(&S);
|
||||||
| ----------- ^^ the trait `Foo` is not implemented for `S`
|
| ^^^^^^^^^^^^^^^
|
||||||
| |
|
|
||||||
| required by a bound introduced by this call
|
|
||||||
|
|
|
||||||
note: required by a bound in `equals_self`
|
|
||||||
--> $DIR/call-generic-method-nonconst.rs:18:25
|
|
||||||
|
|
|
||||||
LL | const fn equals_self<T: ~const Foo>(t: &T) -> bool {
|
|
||||||
| ^^^^^^^^^^ required by this bound in `equals_self`
|
|
||||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
|
||||||
|
|
|
||||||
LL | pub const EQ: bool where S: Foo = equals_self(&S);
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,13 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors; 1 warning emitted
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/call-generic-method-pass.rs:19:32
|
||||||
|
|
|
||||||
|
LL | const fn equals_self<T: ~const PartialEq>(t: &T) -> bool {
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ trait NonConst {}
|
||||||
|
|
||||||
const fn perform<T: ~const NonConst>() {}
|
const fn perform<T: ~const NonConst>() {}
|
||||||
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
|
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
|
||||||
fn operate<T: const NonConst>() {}
|
fn operate<T: const NonConst>() {}
|
||||||
//~^ ERROR `const` can only be applied to `#[const_trait]` traits
|
//~^ ERROR `const` can only be applied to `#[const_trait]` traits
|
||||||
|
|
|
@ -18,11 +18,19 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn perform<T: ~const NonConst>() {}
|
LL | const fn perform<T: ~const NonConst>() {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-bounds-non-const-trait.rs:6:28
|
||||||
|
|
|
||||||
|
LL | const fn perform<T: ~const NonConst>() {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `const` can only be applied to `#[const_trait]` traits
|
error: `const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-bounds-non-const-trait.rs:9:21
|
--> $DIR/const-bounds-non-const-trait.rs:10:21
|
||||||
|
|
|
|
||||||
LL | fn operate<T: const NonConst>() {}
|
LL | fn operate<T: const NonConst>() {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors; 1 warning emitted
|
error: aborting due to 4 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-closure-trait-method-fail.rs:5:1
|
--> $DIR/const-closure-trait-method-fail.rs:14:39
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^^^^^^^^^^^
|
||||||
LL | trait Tr {
|
|
||||||
LL | fn a(self) -> i32;
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-closure-trait-method-fail.rs:14:39
|
--> $DIR/const-closure-trait-method-fail.rs:14:39
|
||||||
|
|
|
|
||||||
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
|
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error[E0015]: cannot call non-const closure in constant functions
|
||||||
--> $DIR/const-closure-trait-method-fail.rs:15:5
|
--> $DIR/const-closure-trait-method-fail.rs:15:5
|
||||||
|
@ -31,5 +30,4 @@ LL + #![feature(effects)]
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
error[E0049]: method `a` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-closure-trait-method.rs:5:1
|
--> $DIR/const-closure-trait-method.rs:14:39
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^^^^^^^^^^^
|
||||||
LL | trait Tr {
|
|
||||||
LL | fn a(self) -> i32;
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-closure-trait-method.rs:14:39
|
--> $DIR/const-closure-trait-method.rs:14:39
|
||||||
|
|
|
|
||||||
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
|
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32>(x: T) -> i32 {
|
||||||
| ^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error[E0015]: cannot call non-const closure in constant functions
|
||||||
--> $DIR/const-closure-trait-method.rs:15:5
|
--> $DIR/const-closure-trait-method.rs:15:5
|
||||||
|
@ -31,5 +30,4 @@ LL + #![feature(effects)]
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
|
@ -16,12 +16,44 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | F: ~const Fn() -> u8,
|
LL | F: ~const Fn() -> u8,
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-closures.rs:8:19
|
||||||
|
|
|
||||||
|
LL | F: ~const FnOnce() -> u8,
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-closures.rs:9:19
|
||||||
|
|
|
||||||
|
LL | F: ~const FnMut() -> u8,
|
||||||
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-closures.rs:10:19
|
||||||
|
|
|
||||||
|
LL | F: ~const Fn() -> u8,
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-closures.rs:23:27
|
--> $DIR/const-closures.rs:23:27
|
||||||
|
|
|
|
||||||
LL | const fn answer<F: ~const Fn() -> u8>(f: &F) -> u8 {
|
LL | const fn answer<F: ~const Fn() -> u8>(f: &F) -> u8 {
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-closures.rs:23:27
|
||||||
|
|
|
||||||
|
LL | const fn answer<F: ~const Fn() -> u8>(f: &F) -> u8 {
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const closure in constant functions
|
error[E0015]: cannot call non-const closure in constant functions
|
||||||
--> $DIR/const-closures.rs:24:5
|
--> $DIR/const-closures.rs:24:5
|
||||||
|
|
|
|
||||||
|
@ -70,6 +102,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||||
LL + #![feature(effects)]
|
LL + #![feature(effects)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 7 previous errors
|
error: aborting due to 11 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0015`.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,21 +1,8 @@
|
||||||
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
|
error[E0277]: the trait bound `NonConstImpl: ~const ConstDefaultFn` is not satisfied
|
||||||
--> $DIR/const-default-method-bodies.rs:26:18
|
--> $DIR/const-default-method-bodies.rs:26:5
|
||||||
|
|
|
|
||||||
LL | NonConstImpl.a();
|
LL | NonConstImpl.a();
|
||||||
| ^ the trait `ConstDefaultFn` is not implemented for `NonConstImpl`
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
note: required by a bound in `ConstDefaultFn::a`
|
|
||||||
--> $DIR/const-default-method-bodies.rs:5:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `ConstDefaultFn::a`
|
|
||||||
...
|
|
||||||
LL | fn a(self) {
|
|
||||||
| - required by a bound in this associated function
|
|
||||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
|
||||||
|
|
|
||||||
LL | const fn test() where NonConstImpl: ConstDefaultFn {
|
|
||||||
| ++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
|
LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-drop-bound.rs:9:68
|
||||||
|
|
|
||||||
|
LL | const fn foo<T, E>(res: Result<T, E>) -> Option<T> where E: ~const Destruct {
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-drop-bound.rs:20:15
|
--> $DIR/const-drop-bound.rs:20:15
|
||||||
|
|
|
|
||||||
|
@ -16,12 +24,28 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | E: ~const Destruct,
|
LL | E: ~const Destruct,
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-drop-bound.rs:20:15
|
||||||
|
|
|
||||||
|
LL | T: ~const Destruct,
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-drop-bound.rs:21:15
|
||||||
|
|
|
||||||
|
LL | E: ~const Destruct,
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0493]: destructor of `E` cannot be evaluated at compile-time
|
error[E0493]: destructor of `E` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-drop-bound.rs:12:13
|
--> $DIR/const-drop-bound.rs:12:13
|
||||||
|
|
|
|
||||||
LL | Err(_e) => None,
|
LL | Err(_e) => None,
|
||||||
| ^^ the destructor for this type cannot be evaluated in constant functions
|
| ^^ the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 7 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0493`.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-drop-fail-2.rs:20:26
|
||||||
|
|
|
||||||
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-drop-fail-2.rs:20:36
|
--> $DIR/const-drop-fail-2.rs:20:36
|
||||||
|
|
|
|
||||||
|
@ -33,7 +41,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||||
LL + #![feature(effects)]
|
LL + #![feature(effects)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0493.
|
Some errors have detailed explanations: E0015, E0493.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-drop-fail.rs:23:26
|
||||||
|
|
|
||||||
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-drop-fail.rs:23:36
|
--> $DIR/const-drop-fail.rs:23:36
|
||||||
|
|
|
|
||||||
|
@ -71,7 +79,7 @@ LL | | }
|
||||||
| |_- in this macro invocation
|
| |_- in this macro invocation
|
||||||
= note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `check_all` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0080, E0493.
|
Some errors have detailed explanations: E0080, E0493.
|
||||||
For more information about an error, try `rustc --explain E0080`.
|
For more information about an error, try `rustc --explain E0080`.
|
||||||
|
|
|
@ -13,6 +13,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn check<T: ~const Destruct>(_: T) {}
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-drop-fail.rs:23:26
|
||||||
|
|
|
||||||
|
LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/const-drop-fail.rs:23:36
|
--> $DIR/const-drop-fail.rs:23:36
|
||||||
|
|
|
|
||||||
|
@ -21,6 +29,6 @@ LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||||
| |
|
| |
|
||||||
| the destructor for this type cannot be evaluated in constant functions
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0493`.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn a<T: ~const Destruct>(_: T) {}
|
LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-drop.rs:53:5
|
--> $DIR/const-drop.rs:18:22
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^^
|
||||||
LL | pub trait SomeTrait {
|
|
||||||
LL | fn foo();
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
|
|
||||||
--> $DIR/const-drop.rs:53:5
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
|
||||||
LL | pub trait SomeTrait {
|
|
||||||
LL | fn foo();
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
@ -78,7 +66,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||||
LL + #![feature(effects)]
|
LL + #![feature(effects)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049, E0493.
|
Some errors have detailed explanations: E0015, E0493.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -40,23 +40,11 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn a<T: ~const Destruct>(_: T) {}
|
LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/const-drop.rs:53:5
|
--> $DIR/const-drop.rs:18:22
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | const fn a<T: ~const Destruct>(_: T) {}
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^^
|
||||||
LL | pub trait SomeTrait {
|
|
||||||
LL | fn foo();
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error[E0049]: associated function `foo` has 1 const parameter but its trait declaration has 0 const parameters
|
|
||||||
--> $DIR/const-drop.rs:53:5
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
|
||||||
LL | pub trait SomeTrait {
|
|
||||||
LL | fn foo();
|
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
@ -80,7 +68,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
|
||||||
LL + #![feature(effects)]
|
LL + #![feature(effects)]
|
||||||
|
|
|
|
||||||
|
|
||||||
error: aborting due to 9 previous errors
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049, E0493.
|
Some errors have detailed explanations: E0015, E0493.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
//@ known-bug: #110395
|
//@ known-bug: #110395
|
||||||
|
//@ failure-status: 101
|
||||||
|
//@ dont-check-compiler-stderr
|
||||||
// FIXME(effects) check-pass
|
// FIXME(effects) check-pass
|
||||||
//@ compile-flags: -Znext-solver
|
//@ compile-flags: -Znext-solver
|
||||||
|
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
error[E0277]: the trait bound `fn() {foo}: const FnOnce()` is not satisfied
|
|
||||||
--> $DIR/const-fns-are-early-bound.rs:31:17
|
|
||||||
|
|
|
||||||
LL | is_const_fn(foo);
|
|
||||||
| ----------- ^^^ the trait `FnOnce()` is not implemented for fn item `fn() {foo}`
|
|
||||||
| |
|
|
||||||
| required by a bound introduced by this call
|
|
||||||
|
|
|
||||||
note: required by a bound in `is_const_fn`
|
|
||||||
--> $DIR/const-fns-are-early-bound.rs:25:12
|
|
||||||
|
|
|
||||||
LL | fn is_const_fn<F>(_: F)
|
|
||||||
| ----------- required by a bound in this function
|
|
||||||
LL | where
|
|
||||||
LL | F: const FnOnce<()>,
|
|
||||||
| ^^^^^^^^^^^^^^^^ required by this bound in `is_const_fn`
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0277`.
|
|
|
@ -1,249 +0,0 @@
|
||||||
error[E0635]: unknown feature `const_cmp`
|
|
||||||
--> $DIR/const-impl-trait.rs:8:5
|
|
||||||
|
|
|
||||||
LL | const_cmp,
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: using `#![feature(effects)]` without enabling next trait solver globally
|
|
||||||
|
|
|
||||||
= note: the next trait solver must be enabled globally for the effects feature to work correctly
|
|
||||||
= help: use `-Znext-solver` to enable
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:13:30
|
|
||||||
|
|
|
||||||
LL | const fn cmp(a: &impl ~const PartialEq) -> bool {
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:17:30
|
|
||||||
|
|
|
||||||
LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct)
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:17:49
|
|
||||||
|
|
|
||||||
LL | const fn wrap(x: impl ~const PartialEq + ~const Destruct)
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:18:20
|
|
||||||
|
|
|
||||||
LL | -> impl ~const PartialEq + ~const Destruct
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:18:39
|
|
||||||
|
|
|
||||||
LL | -> impl ~const PartialEq + ~const Destruct
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:18:20
|
|
||||||
|
|
|
||||||
LL | -> impl ~const PartialEq + ~const Destruct
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:18:39
|
|
||||||
|
|
|
||||||
LL | -> impl ~const PartialEq + ~const Destruct
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:29
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:48
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:29:29
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:29:48
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:29:29
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:29:48
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy {
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:50:41
|
|
||||||
|
|
|
||||||
LL | const fn apit(_: impl ~const T + ~const Destruct) {}
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:54:73
|
|
||||||
|
|
|
||||||
LL | const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:29
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:48
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:29
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:48
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:29
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error: `~const` can only be applied to `#[const_trait]` traits
|
|
||||||
--> $DIR/const-impl-trait.rs:25:48
|
|
||||||
|
|
|
||||||
LL | fn huh() -> impl ~const PartialEq + ~const Destruct + Copy;
|
|
||||||
| ^^^^^^^^
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:37:26
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) == wrap(123));
|
|
||||||
| ^^^^^^^^^- value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:37:26
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) == wrap(123));
|
|
||||||
| ^^^^^^^^^- value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:37:13
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) == wrap(123));
|
|
||||||
| ^^^^^^^^^ - value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:37:13
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) == wrap(123));
|
|
||||||
| ^^^^^^^^^ - value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:38:26
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) != wrap(456));
|
|
||||||
| ^^^^^^^^^- value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:38:26
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) != wrap(456));
|
|
||||||
| ^^^^^^^^^- value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:38:13
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) != wrap(456));
|
|
||||||
| ^^^^^^^^^ - value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl PartialEq + Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:38:13
|
|
||||||
|
|
|
||||||
LL | assert!(wrap(123) != wrap(456));
|
|
||||||
| ^^^^^^^^^ - value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constants
|
|
||||||
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl ~const T + ~const Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:50:15
|
|
||||||
|
|
|
||||||
LL | const fn apit(_: impl ~const T + ~const Destruct) {}
|
|
||||||
| ^ - value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constant functions
|
|
||||||
|
|
||||||
error[E0493]: destructor of `impl IntoIterator<Item : ~const T> + ~const Destruct` cannot be evaluated at compile-time
|
|
||||||
--> $DIR/const-impl-trait.rs:54:27
|
|
||||||
|
|
|
||||||
LL | const fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T> + ~const Destruct) {}
|
|
||||||
| ^ - value is dropped here
|
|
||||||
| |
|
|
||||||
| the destructor for this type cannot be evaluated in constant functions
|
|
||||||
|
|
||||||
error: aborting due to 33 previous errors
|
|
||||||
|
|
||||||
Some errors have detailed explanations: E0493, E0635.
|
|
||||||
For more information about an error, try `rustc --explain E0493`.
|
|
|
@ -30,5 +30,14 @@ LL | #[derive_const(PartialEq)]
|
||||||
|
|
|
|
||||||
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 3 previous errors; 1 warning emitted
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/derive-const-with-params.rs:7:16
|
||||||
|
|
|
||||||
|
LL | #[derive_const(PartialEq)]
|
||||||
|
| ^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
= note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,8 @@
|
||||||
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
|
error[E0277]: the trait bound `cross_crate::NonConst: ~const cross_crate::MyTrait` is not satisfied
|
||||||
--> $DIR/cross-crate.rs:19:14
|
--> $DIR/cross-crate.rs:19:5
|
||||||
|
|
|
|
||||||
LL | NonConst.func();
|
LL | NonConst.func();
|
||||||
| ^^^^ the trait `cross_crate::MyTrait` is not implemented for `cross_crate::NonConst`
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
note: required by a bound in `func`
|
|
||||||
--> $DIR/auxiliary/cross-crate.rs:5:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `MyTrait::func`
|
|
||||||
...
|
|
||||||
LL | fn func(self);
|
|
||||||
| ---- required by a bound in this associated function
|
|
||||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
|
||||||
|
|
|
||||||
LL | const fn const_context() where cross_crate::NonConst: cross_crate::MyTrait {
|
|
||||||
| +++++++++++++++++++++++++++++++++++++++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,8 @@
|
||||||
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
||||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:12
|
--> $DIR/default-method-body-is-const-same-trait-ck.rs:10:9
|
||||||
|
|
|
|
||||||
LL | ().a()
|
LL | ().a()
|
||||||
| ^ the trait `Tr` is not implemented for `()`
|
| ^^^^^^
|
||||||
|
|
|
||||||
note: required by a bound in `Tr::a`
|
|
||||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:5:1
|
|
||||||
|
|
|
||||||
LL | #[const_trait]
|
|
||||||
| ^^^^^^^^^^^^^^ required by this bound in `Tr::a`
|
|
||||||
LL | pub trait Tr {
|
|
||||||
LL | fn a(&self) {}
|
|
||||||
| - required by a bound in this associated function
|
|
||||||
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
|
|
||||||
|
|
|
||||||
LL | pub trait Tr where (): Tr {
|
|
||||||
| ++++++++++++
|
|
||||||
|
|
||||||
error: aborting due to 1 previous error
|
error: aborting due to 1 previous error
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
error: the compiler unexpectedly panicked. this is a bug.
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
||||||
query stack during panic:
|
query stack during panic:
|
||||||
#0 [check_well_formed] checking that `<impl at $DIR/minicore.rs:459:1: 459:36>` is well-formed
|
#0 [typeck] type-checking `Clone::clone_from`
|
||||||
#1 [check_mod_type_wf] checking that types are well-formed in top-level module
|
#1 [analysis] running analysis passes on this crate
|
||||||
end of query stack
|
end of query stack
|
||||||
|
|
||||||
error: the compiler unexpectedly panicked. this is a bug.
|
error: the compiler unexpectedly panicked. this is a bug.
|
||||||
|
|
||||||
query stack during panic:
|
query stack during panic:
|
||||||
#0 [check_well_formed] checking that `drop` is well-formed
|
#0 [typeck] type-checking `test_const_eval_select`
|
||||||
#1 [check_mod_type_wf] checking that types are well-formed in top-level module
|
#1 [analysis] running analysis passes on this crate
|
||||||
end of query stack
|
end of query stack
|
||||||
|
|
|
@ -16,17 +16,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
|
||||||
--> $DIR/no-explicit-const-params-cross-crate.rs:16:12
|
--> $DIR/no-explicit-const-params-cross-crate.rs:16:12
|
||||||
|
|
|
|
||||||
LL | <() as Bar<false>>::bar();
|
LL | <() as Bar<false>>::bar();
|
||||||
| ^^^ expected 0 generic arguments
|
| ^^^------- help: remove the unnecessary generics
|
||||||
|
| |
|
||||||
|
| expected 0 generic arguments
|
||||||
|
|
|
|
||||||
note: trait defined here, with 0 generic parameters
|
note: trait defined here, with 0 generic parameters
|
||||||
--> $DIR/auxiliary/cross-crate.rs:8:11
|
--> $DIR/auxiliary/cross-crate.rs:8:11
|
||||||
|
|
|
|
||||||
LL | pub trait Bar {
|
LL | pub trait Bar {
|
||||||
| ^^^
|
| ^^^
|
||||||
help: replace the generic bound with the associated type
|
|
||||||
|
|
|
||||||
LL | <() as Bar< = false>>::bar();
|
|
||||||
| +
|
|
||||||
|
|
||||||
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
|
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
--> $DIR/no-explicit-const-params-cross-crate.rs:7:5
|
--> $DIR/no-explicit-const-params-cross-crate.rs:7:5
|
||||||
|
@ -46,17 +44,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
|
||||||
--> $DIR/no-explicit-const-params-cross-crate.rs:9:12
|
--> $DIR/no-explicit-const-params-cross-crate.rs:9:12
|
||||||
|
|
|
|
||||||
LL | <() as Bar<true>>::bar();
|
LL | <() as Bar<true>>::bar();
|
||||||
| ^^^ expected 0 generic arguments
|
| ^^^------ help: remove the unnecessary generics
|
||||||
|
| |
|
||||||
|
| expected 0 generic arguments
|
||||||
|
|
|
|
||||||
note: trait defined here, with 0 generic parameters
|
note: trait defined here, with 0 generic parameters
|
||||||
--> $DIR/auxiliary/cross-crate.rs:8:11
|
--> $DIR/auxiliary/cross-crate.rs:8:11
|
||||||
|
|
|
|
||||||
LL | pub trait Bar {
|
LL | pub trait Bar {
|
||||||
| ^^^
|
| ^^^
|
||||||
help: replace the generic bound with the associated type
|
|
||||||
|
|
|
||||||
LL | <() as Bar< = true>>::bar();
|
|
||||||
| +
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
|
|
@ -23,5 +23,4 @@ const FOO: () = {
|
||||||
//~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
|
//~^ ERROR: function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
<() as Bar<false>>::bar();
|
<() as Bar<false>>::bar();
|
||||||
//~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
|
//~^ ERROR: trait takes 0 generic arguments but 1 generic argument was supplied
|
||||||
//~| ERROR: mismatched types
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,26 +30,15 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
|
||||||
--> $DIR/no-explicit-const-params.rs:24:12
|
--> $DIR/no-explicit-const-params.rs:24:12
|
||||||
|
|
|
|
||||||
LL | <() as Bar<false>>::bar();
|
LL | <() as Bar<false>>::bar();
|
||||||
| ^^^ expected 0 generic arguments
|
| ^^^------- help: remove the unnecessary generics
|
||||||
|
| |
|
||||||
|
| expected 0 generic arguments
|
||||||
|
|
|
|
||||||
note: trait defined here, with 0 generic parameters
|
note: trait defined here, with 0 generic parameters
|
||||||
--> $DIR/no-explicit-const-params.rs:6:7
|
--> $DIR/no-explicit-const-params.rs:6:7
|
||||||
|
|
|
|
||||||
LL | trait Bar {
|
LL | trait Bar {
|
||||||
| ^^^
|
| ^^^
|
||||||
help: replace the generic bound with the associated type
|
|
||||||
|
|
|
||||||
LL | <() as Bar< = false>>::bar();
|
|
||||||
| +
|
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/no-explicit-const-params.rs:24:5
|
|
||||||
|
|
|
||||||
LL | <() as Bar<false>>::bar();
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `false`, found `true`
|
|
||||||
|
|
|
||||||
= note: expected constant `false`
|
|
||||||
found constant `true`
|
|
||||||
|
|
||||||
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
|
error[E0107]: function takes 0 generic arguments but 1 generic argument was supplied
|
||||||
--> $DIR/no-explicit-const-params.rs:15:5
|
--> $DIR/no-explicit-const-params.rs:15:5
|
||||||
|
@ -69,19 +58,16 @@ error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplie
|
||||||
--> $DIR/no-explicit-const-params.rs:17:12
|
--> $DIR/no-explicit-const-params.rs:17:12
|
||||||
|
|
|
|
||||||
LL | <() as Bar<true>>::bar();
|
LL | <() as Bar<true>>::bar();
|
||||||
| ^^^ expected 0 generic arguments
|
| ^^^------ help: remove the unnecessary generics
|
||||||
|
| |
|
||||||
|
| expected 0 generic arguments
|
||||||
|
|
|
|
||||||
note: trait defined here, with 0 generic parameters
|
note: trait defined here, with 0 generic parameters
|
||||||
--> $DIR/no-explicit-const-params.rs:6:7
|
--> $DIR/no-explicit-const-params.rs:6:7
|
||||||
|
|
|
|
||||||
LL | trait Bar {
|
LL | trait Bar {
|
||||||
| ^^^
|
| ^^^
|
||||||
help: replace the generic bound with the associated type
|
|
||||||
|
|
|
||||||
LL | <() as Bar< = true>>::bar();
|
|
||||||
| +
|
|
||||||
|
|
||||||
error: aborting due to 6 previous errors; 1 warning emitted
|
error: aborting due to 5 previous errors; 1 warning emitted
|
||||||
|
|
||||||
Some errors have detailed explanations: E0107, E0308.
|
For more information about this error, try `rustc --explain E0107`.
|
||||||
For more information about an error, try `rustc --explain E0107`.
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
//@ check-fail
|
|
||||||
// Fixes #119830
|
// Fixes #119830
|
||||||
|
|
||||||
#![feature(effects)] //~ WARN the feature `effects` is incomplete
|
#![feature(effects)] //~ WARN the feature `effects` is incomplete
|
||||||
|
@ -15,7 +14,9 @@ impl<T> const Foo for T {}
|
||||||
impl<T> const Foo for T where T: const Specialize {}
|
impl<T> const Foo for T where T: const Specialize {}
|
||||||
//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||||
//~| error: `const` can only be applied to `#[const_trait]` traits
|
//~| error: `const` can only be applied to `#[const_trait]` traits
|
||||||
|
//~| error: `const` can only be applied to `#[const_trait]` traits
|
||||||
//~| error: specialization impl does not specialize any associated items
|
//~| error: specialization impl does not specialize any associated items
|
||||||
//~| error: cannot specialize on trait `Specialize`
|
//~| error: cannot specialize on trait `Specialize`
|
||||||
|
//~| ERROR cannot specialize on predicate
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
|
warning: the feature `effects` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
--> $DIR/spec-effectvar-ice.rs:4:12
|
--> $DIR/spec-effectvar-ice.rs:3:12
|
||||||
|
|
|
|
||||||
LL | #![feature(effects)]
|
LL | #![feature(effects)]
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
@ -13,7 +13,7 @@ error: using `#![feature(effects)]` without enabling next trait solver globally
|
||||||
= help: use `-Znext-solver` to enable
|
= help: use `-Znext-solver` to enable
|
||||||
|
|
||||||
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||||
--> $DIR/spec-effectvar-ice.rs:12:15
|
--> $DIR/spec-effectvar-ice.rs:11:15
|
||||||
|
|
|
|
||||||
LL | trait Foo {}
|
LL | trait Foo {}
|
||||||
| - help: mark `Foo` as const: `#[const_trait]`
|
| - help: mark `Foo` as const: `#[const_trait]`
|
||||||
|
@ -25,7 +25,7 @@ LL | impl<T> const Foo for T {}
|
||||||
= note: adding a non-const method body in the future would be a breaking change
|
= note: adding a non-const method body in the future would be a breaking change
|
||||||
|
|
||||||
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
error: const `impl` for trait `Foo` which is not marked with `#[const_trait]`
|
||||||
--> $DIR/spec-effectvar-ice.rs:15:15
|
--> $DIR/spec-effectvar-ice.rs:14:15
|
||||||
|
|
|
|
||||||
LL | trait Foo {}
|
LL | trait Foo {}
|
||||||
| - help: mark `Foo` as const: `#[const_trait]`
|
| - help: mark `Foo` as const: `#[const_trait]`
|
||||||
|
@ -37,28 +37,42 @@ LL | impl<T> const Foo for T where T: const Specialize {}
|
||||||
= note: adding a non-const method body in the future would be a breaking change
|
= note: adding a non-const method body in the future would be a breaking change
|
||||||
|
|
||||||
error: `const` can only be applied to `#[const_trait]` traits
|
error: `const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/spec-effectvar-ice.rs:15:40
|
--> $DIR/spec-effectvar-ice.rs:14:40
|
||||||
|
|
|
|
||||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: `const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/spec-effectvar-ice.rs:14:40
|
||||||
|
|
|
||||||
|
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: specialization impl does not specialize any associated items
|
error: specialization impl does not specialize any associated items
|
||||||
--> $DIR/spec-effectvar-ice.rs:15:1
|
--> $DIR/spec-effectvar-ice.rs:14:1
|
||||||
|
|
|
|
||||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
note: impl is a specialization of this impl
|
note: impl is a specialization of this impl
|
||||||
--> $DIR/spec-effectvar-ice.rs:12:1
|
--> $DIR/spec-effectvar-ice.rs:11:1
|
||||||
|
|
|
|
||||||
LL | impl<T> const Foo for T {}
|
LL | impl<T> const Foo for T {}
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: cannot specialize on trait `Specialize`
|
error: cannot specialize on predicate `T: const Specialize`
|
||||||
--> $DIR/spec-effectvar-ice.rs:15:34
|
--> $DIR/spec-effectvar-ice.rs:14:34
|
||||||
|
|
|
|
||||||
LL | impl<T> const Foo for T where T: const Specialize {}
|
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 6 previous errors; 1 warning emitted
|
error: cannot specialize on trait `Specialize`
|
||||||
|
--> $DIR/spec-effectvar-ice.rs:14:34
|
||||||
|
|
|
||||||
|
LL | impl<T> const Foo for T where T: const Specialize {}
|
||||||
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
|
|
@ -3,5 +3,6 @@
|
||||||
|
|
||||||
const fn with_positive<F: ~const Fn()>() {}
|
const fn with_positive<F: ~const Fn()>() {}
|
||||||
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
|
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
|
||||||
pub fn main() {}
|
pub fn main() {}
|
||||||
|
|
|
@ -9,5 +9,13 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn with_positive<F: ~const Fn()>() {}
|
LL | const fn with_positive<F: ~const Fn()>() {}
|
||||||
| ^^^^
|
| ^^^^
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/ice-123664-unexpected-bound-var.rs:4:34
|
||||||
|
|
|
||||||
|
LL | const fn with_positive<F: ~const Fn()>() {}
|
||||||
|
| ^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,14 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | const fn a<T: ~const Destruct>(t: T) {}
|
LL | const fn a<T: ~const Destruct>(t: T) {}
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/issue-92111.rs:20:22
|
||||||
|
|
|
||||||
|
LL | const fn a<T: ~const Destruct>(t: T) {}
|
||||||
|
| ^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||||
--> $DIR/issue-92111.rs:20:32
|
--> $DIR/issue-92111.rs:20:32
|
||||||
|
|
|
|
||||||
|
@ -12,6 +20,6 @@ LL | const fn a<T: ~const Destruct>(t: T) {}
|
||||||
| |
|
| |
|
||||||
| the destructor for this type cannot be evaluated in constant functions
|
| the destructor for this type cannot be evaluated in constant functions
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0493`.
|
For more information about this error, try `rustc --explain E0493`.
|
||||||
|
|
|
@ -4,14 +4,13 @@ error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
LL | impl<A, B> const Convert<B> for A where B: ~const From<A> {
|
LL | impl<A, B> const Convert<B> for A where B: ~const From<A> {
|
||||||
| ^^^^^^^
|
| ^^^^^^^
|
||||||
|
|
||||||
error[E0049]: method `to` has 1 const parameter but its trait declaration has 0 const parameters
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
--> $DIR/non-const-op-in-closure-in-const.rs:5:1
|
--> $DIR/non-const-op-in-closure-in-const.rs:10:51
|
||||||
|
|
|
|
||||||
LL | #[const_trait]
|
LL | impl<A, B> const Convert<B> for A where B: ~const From<A> {
|
||||||
| ^^^^^^^^^^^^^^ found 1 const parameter
|
| ^^^^^^^
|
||||||
LL | trait Convert<T> {
|
|
|
||||||
LL | fn to(self) -> T;
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
| - expected 0 const parameters
|
|
||||||
|
|
||||||
error[E0015]: cannot call non-const fn `<B as From<A>>::from` in constant functions
|
error[E0015]: cannot call non-const fn `<B as From<A>>::from` in constant functions
|
||||||
--> $DIR/non-const-op-in-closure-in-const.rs:12:9
|
--> $DIR/non-const-op-in-closure-in-const.rs:12:9
|
||||||
|
@ -27,5 +26,4 @@ LL + #![feature(effects)]
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0049.
|
For more information about this error, try `rustc --explain E0015`.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
|
||||||
|
|
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