mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-16 17:03:35 +00:00
Remove constness from TraitPredicate
This commit is contained in:
parent
7637653b9f
commit
4fec845c3f
@ -90,11 +90,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
) {
|
||||
self.prove_predicate(
|
||||
ty::Binder::dummy(ty::PredicateKind::Clause(ty::ClauseKind::Trait(
|
||||
ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
},
|
||||
ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive },
|
||||
))),
|
||||
locations,
|
||||
category,
|
||||
|
@ -746,6 +746,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
}
|
||||
|
||||
// Attempting to call a trait method?
|
||||
// FIXME(effects) do we need this?
|
||||
if let Some(trait_id) = tcx.trait_of_item(callee) {
|
||||
trace!("attempting to call a trait method");
|
||||
if !self.tcx.features().const_trait_impl {
|
||||
@ -761,7 +762,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
||||
}
|
||||
|
||||
let trait_ref = TraitRef::from_method(tcx, trait_id, fn_args);
|
||||
let trait_ref = trait_ref.with_constness(ty::BoundConstness::ConstIfConst);
|
||||
let obligation =
|
||||
Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
|
||||
|
||||
|
@ -155,12 +155,12 @@ impl Qualif for NeedsNonConstDrop {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME(effects) constness
|
||||
let obligation = Obligation::new(
|
||||
cx.tcx,
|
||||
ObligationCause::dummy_with_span(cx.body.span),
|
||||
cx.param_env,
|
||||
ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty])
|
||||
.with_constness(ty::BoundConstness::ConstIfConst),
|
||||
ty::TraitRef::from_lang_item(cx.tcx, LangItem::Destruct, cx.body.span, [ty]),
|
||||
);
|
||||
|
||||
let infcx = cx.tcx.infer_ctxt().build();
|
||||
|
@ -713,7 +713,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
);
|
||||
|
||||
debug!(?poly_trait_ref, ?assoc_bindings);
|
||||
bounds.push_trait_bound(tcx, poly_trait_ref, span, constness, polarity);
|
||||
bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
|
||||
|
||||
let mut dup_bindings = FxHashMap::default();
|
||||
for binding in &assoc_bindings {
|
||||
|
@ -62,11 +62,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
match bound_pred.skip_binder() {
|
||||
ty::ClauseKind::Trait(trait_pred) => {
|
||||
assert_eq!(trait_pred.polarity, ty::ImplPolarity::Positive);
|
||||
trait_bounds.push((
|
||||
bound_pred.rebind(trait_pred.trait_ref),
|
||||
span,
|
||||
trait_pred.constness,
|
||||
));
|
||||
trait_bounds.push((bound_pred.rebind(trait_pred.trait_ref), span));
|
||||
}
|
||||
ty::ClauseKind::Projection(proj) => {
|
||||
projection_bounds.push((bound_pred.rebind(proj), span));
|
||||
@ -86,7 +82,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// Expand trait aliases recursively and check that only one regular (non-auto) trait
|
||||
// is used and no 'maybe' bounds are used.
|
||||
let expanded_traits =
|
||||
traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b, _)| (a, b)));
|
||||
traits::expand_trait_aliases(tcx, trait_bounds.iter().map(|&(a, b)| (a, b)));
|
||||
|
||||
let (mut auto_traits, regular_traits): (Vec<_>, Vec<_>) = expanded_traits
|
||||
.filter(|i| i.trait_ref().self_ty().skip_binder() == dummy_self)
|
||||
@ -126,7 +122,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
if regular_traits.is_empty() && auto_traits.is_empty() {
|
||||
let trait_alias_span = trait_bounds
|
||||
.iter()
|
||||
.map(|&(trait_ref, _, _)| trait_ref.def_id())
|
||||
.map(|&(trait_ref, _)| trait_ref.def_id())
|
||||
.find(|&trait_ref| tcx.is_trait_alias(trait_ref))
|
||||
.map(|trait_ref| tcx.def_span(trait_ref));
|
||||
let reported =
|
||||
@ -157,10 +153,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
|
||||
let regular_traits_refs_spans = trait_bounds
|
||||
.into_iter()
|
||||
.filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
||||
.filter(|(trait_ref, _)| !tcx.trait_is_auto(trait_ref.def_id()));
|
||||
|
||||
for (base_trait_ref, span, constness) in regular_traits_refs_spans {
|
||||
assert_eq!(constness, ty::BoundConstness::NotConst);
|
||||
for (base_trait_ref, span) in regular_traits_refs_spans {
|
||||
let base_pred: ty::Predicate<'tcx> = base_trait_ref.to_predicate(tcx);
|
||||
for pred in traits::elaborate(tcx, [base_pred]) {
|
||||
debug!("conv_object_ty_poly_trait_ref: observing object predicate `{:?}`", pred);
|
||||
|
@ -42,13 +42,12 @@ impl<'tcx> Bounds<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
span: Span,
|
||||
constness: ty::BoundConstness,
|
||||
polarity: ty::ImplPolarity,
|
||||
) {
|
||||
self.clauses.push((
|
||||
trait_ref
|
||||
.map_bound(|trait_ref| {
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness, polarity })
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
|
||||
})
|
||||
.to_predicate(tcx),
|
||||
span,
|
||||
|
@ -194,7 +194,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
|
||||
// We match on both `ty::ImplPolarity` and `ast::ImplPolarity` just to get the `!` span.
|
||||
match (tcx.impl_polarity(def_id), impl_.polarity) {
|
||||
(ty::ImplPolarity::Positive, _) => {
|
||||
check_impl(tcx, item, impl_.self_ty, &impl_.of_trait, impl_.constness);
|
||||
check_impl(tcx, item, impl_.self_ty, &impl_.of_trait);
|
||||
}
|
||||
(ty::ImplPolarity::Negative, ast::ImplPolarity::Negative(span)) => {
|
||||
// FIXME(#27579): what amount of WF checking do we need for neg impls?
|
||||
@ -1191,7 +1191,6 @@ fn check_impl<'tcx>(
|
||||
item: &'tcx hir::Item<'tcx>,
|
||||
ast_self_ty: &hir::Ty<'_>,
|
||||
ast_trait_ref: &Option<hir::TraitRef<'_>>,
|
||||
constness: hir::Constness,
|
||||
) {
|
||||
enter_wf_checking_ctxt(tcx, item.span, item.owner_id.def_id, |wfcx| {
|
||||
match ast_trait_ref {
|
||||
@ -1205,14 +1204,8 @@ fn check_impl<'tcx>(
|
||||
Some(WellFormedLoc::Ty(item.hir_id().expect_owner().def_id)),
|
||||
trait_ref,
|
||||
);
|
||||
let trait_pred = ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: match constness {
|
||||
hir::Constness::Const => ty::BoundConstness::ConstIfConst,
|
||||
hir::Constness::NotConst => ty::BoundConstness::NotConst,
|
||||
},
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
};
|
||||
let trait_pred =
|
||||
ty::TraitPredicate { trait_ref, polarity: ty::ImplPolarity::Positive };
|
||||
let mut obligations = traits::wf::trait_obligations(
|
||||
wfcx.infcx,
|
||||
wfcx.param_env,
|
||||
|
@ -10,7 +10,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{GenericPredicates, Generics, ImplTraitInTraitData, ToPredicate};
|
||||
use rustc_span::symbol::{sym, Ident};
|
||||
use rustc_span::symbol::Ident;
|
||||
use rustc_span::{Span, Symbol, DUMMY_SP};
|
||||
|
||||
/// Returns a list of all type predicates (explicit and implicit) for the definition with
|
||||
@ -37,17 +37,10 @@ pub(super) fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredic
|
||||
// from the trait itself that *shouldn't* be shown as the source of
|
||||
// an obligation and instead be skipped. Otherwise we'd use
|
||||
// `tcx.def_span(def_id);`
|
||||
|
||||
let constness = if tcx.has_attr(def_id, sym::const_trait) {
|
||||
ty::BoundConstness::ConstIfConst
|
||||
} else {
|
||||
ty::BoundConstness::NotConst
|
||||
};
|
||||
|
||||
let span = rustc_span::DUMMY_SP;
|
||||
result.predicates =
|
||||
tcx.arena.alloc_from_iter(result.predicates.iter().copied().chain(std::iter::once((
|
||||
ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx),
|
||||
ty::TraitRef::identity(tcx, def_id).to_predicate(tcx),
|
||||
span,
|
||||
))));
|
||||
}
|
||||
@ -204,7 +197,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
||||
// (see below). Recall that a default impl is not itself an impl, but rather a
|
||||
// set of defaults that can be incorporated into another impl.
|
||||
if let Some(trait_ref) = is_default_impl_trait {
|
||||
predicates.insert((trait_ref.without_const().to_predicate(tcx), tcx.def_span(def_id)));
|
||||
predicates.insert((trait_ref.to_predicate(tcx), tcx.def_span(def_id)));
|
||||
}
|
||||
|
||||
// Collect the region predicates that were declared inline as
|
||||
@ -777,8 +770,7 @@ pub(super) fn type_param_predicates(
|
||||
if param_id == item_hir_id {
|
||||
let identity_trait_ref =
|
||||
ty::TraitRef::identity(tcx, item_def_id.to_def_id());
|
||||
extend =
|
||||
Some((identity_trait_ref.without_const().to_predicate(tcx), item.span));
|
||||
extend = Some((identity_trait_ref.to_predicate(tcx), item.span));
|
||||
}
|
||||
generics
|
||||
}
|
||||
|
@ -431,45 +431,13 @@ fn check_predicates<'tcx>(
|
||||
///
|
||||
/// So we make that check in this function and try to raise a helpful error message.
|
||||
fn trait_predicates_eq<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
_tcx: TyCtxt<'tcx>,
|
||||
predicate1: ty::Predicate<'tcx>,
|
||||
predicate2: ty::Predicate<'tcx>,
|
||||
span: Span,
|
||||
_span: Span,
|
||||
) -> bool {
|
||||
let pred1_kind = predicate1.kind().skip_binder();
|
||||
let pred2_kind = predicate2.kind().skip_binder();
|
||||
let (trait_pred1, trait_pred2) = match (pred1_kind, pred2_kind) {
|
||||
(
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred1)),
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred2)),
|
||||
) => (pred1, pred2),
|
||||
// Just use plain syntactic equivalence if either of the predicates aren't
|
||||
// trait predicates or have bound vars.
|
||||
_ => return predicate1 == predicate2,
|
||||
};
|
||||
|
||||
let predicates_equal_modulo_constness = {
|
||||
let pred1_unconsted =
|
||||
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred1 };
|
||||
let pred2_unconsted =
|
||||
ty::TraitPredicate { constness: ty::BoundConstness::NotConst, ..trait_pred2 };
|
||||
pred1_unconsted == pred2_unconsted
|
||||
};
|
||||
|
||||
if !predicates_equal_modulo_constness {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the predicate on the specializing impl is at least as const as
|
||||
// the one on the base.
|
||||
match (trait_pred2.constness, trait_pred1.constness) {
|
||||
(ty::BoundConstness::ConstIfConst, ty::BoundConstness::NotConst) => {
|
||||
tcx.sess.emit_err(errors::MissingTildeConst { span });
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
true
|
||||
// FIXME(effects)
|
||||
predicate1 == predicate2
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
@ -482,7 +450,6 @@ fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tc
|
||||
// items.
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: _,
|
||||
polarity: _,
|
||||
})) => {
|
||||
if !matches!(
|
||||
@ -536,7 +503,6 @@ fn trait_predicate_kind<'tcx>(
|
||||
match predicate.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: _,
|
||||
polarity: _,
|
||||
})) => Some(tcx.trait_def(trait_ref.def_id).specialization_kind),
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(_))
|
||||
|
@ -156,7 +156,6 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
|
||||
match pred.kind().skip_binder() {
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef { def_id: _, args, .. },
|
||||
constness: _,
|
||||
polarity: _,
|
||||
}) => {
|
||||
for subst in &args[1..] {
|
||||
|
@ -2988,7 +2988,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: impl_trait_ref,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
}),
|
||||
|derived| {
|
||||
traits::ImplDerivedObligation(Box::new(
|
||||
|
@ -1461,10 +1461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
param_env,
|
||||
bounds,
|
||||
) {
|
||||
// N.B. We are remapping all predicates to non-const since we don't know if we just
|
||||
// want them as function pointers or we are calling them from a const-context. The
|
||||
// actual checking will occur in `rustc_const_eval::transform::check_consts`.
|
||||
self.register_predicate(obligation.without_const(self.tcx));
|
||||
self.register_predicate(obligation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1856,19 +1856,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if self.adjust_fulfillment_error_for_expr_obligation(error)
|
||||
|| before_span != error.obligation.cause.span
|
||||
{
|
||||
// Store both the predicate and the predicate *without constness*
|
||||
// since sometimes we instantiate and check both of these in a
|
||||
// method call, for example.
|
||||
remap_cause.insert((
|
||||
before_span,
|
||||
error.obligation.predicate,
|
||||
error.obligation.cause.clone(),
|
||||
));
|
||||
remap_cause.insert((
|
||||
before_span,
|
||||
error.obligation.predicate.without_const(self.tcx),
|
||||
error.obligation.cause.clone(),
|
||||
));
|
||||
} else {
|
||||
// If it failed to be adjusted once around, it may be adjusted
|
||||
// via the "remap cause" mapping the second time...
|
||||
|
@ -341,15 +341,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
|
||||
// Construct an obligation
|
||||
let poly_trait_ref = ty::Binder::dummy(trait_ref);
|
||||
(
|
||||
traits::Obligation::new(
|
||||
self.tcx,
|
||||
cause,
|
||||
self.param_env,
|
||||
poly_trait_ref.without_const(),
|
||||
),
|
||||
args,
|
||||
)
|
||||
(traits::Obligation::new(self.tcx, cause, self.param_env, poly_trait_ref), args)
|
||||
}
|
||||
|
||||
/// `lookup_method_in_trait` is used for overloaded operators.
|
||||
|
@ -1599,8 +1599,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
}
|
||||
let predicate =
|
||||
ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx);
|
||||
let predicate = ty::Binder::dummy(trait_ref).to_predicate(self.tcx);
|
||||
parent_pred = Some(predicate);
|
||||
let obligation =
|
||||
traits::Obligation::new(self.tcx, cause.clone(), self.param_env, predicate);
|
||||
|
@ -94,7 +94,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
span,
|
||||
self.body_id,
|
||||
self.param_env,
|
||||
poly_trait_ref.without_const(),
|
||||
poly_trait_ref,
|
||||
);
|
||||
self.predicate_may_hold(&obligation)
|
||||
})
|
||||
|
@ -25,7 +25,7 @@ pub trait TraitEngine<'tcx>: 'tcx {
|
||||
cause,
|
||||
recursion_depth: 0,
|
||||
param_env,
|
||||
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(infcx.tcx),
|
||||
predicate: ty::Binder::dummy(trait_ref).to_predicate(infcx.tcx),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -77,13 +77,6 @@ impl<'tcx> PredicateObligation<'tcx> {
|
||||
recursion_depth: self.recursion_depth,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> PredicateObligation<'tcx> {
|
||||
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) = self.predicate.kind().skip_binder() && trait_pred.is_const_if_const() {
|
||||
self.predicate = tcx.mk_predicate(self.predicate.kind().map_bound(|_| ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred.without_const()))));
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> PolyTraitObligation<'tcx> {
|
||||
|
@ -264,11 +264,7 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> {
|
||||
};
|
||||
|
||||
let obligations =
|
||||
predicates.predicates.iter().enumerate().map(|(index, &(mut clause, span))| {
|
||||
// when parent predicate is non-const, elaborate it to non-const predicates.
|
||||
if data.constness == ty::BoundConstness::NotConst {
|
||||
clause = clause.without_const(tcx);
|
||||
}
|
||||
predicates.predicates.iter().enumerate().map(|(index, &(clause, span))| {
|
||||
elaboratable.child_with_derived_cause(
|
||||
clause.subst_supertrait(tcx, &bound_predicate.rebind(data.trait_ref)),
|
||||
span,
|
||||
|
@ -498,11 +498,9 @@ impl<'tcx> Predicate<'tcx> {
|
||||
.map_bound(|kind| match kind {
|
||||
PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
|
||||
trait_ref,
|
||||
constness,
|
||||
polarity,
|
||||
})) => Some(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
|
||||
trait_ref,
|
||||
constness,
|
||||
polarity: polarity.flip()?,
|
||||
}))),
|
||||
|
||||
@ -513,19 +511,6 @@ impl<'tcx> Predicate<'tcx> {
|
||||
Some(tcx.mk_predicate(kind))
|
||||
}
|
||||
|
||||
pub fn without_const(mut self, tcx: TyCtxt<'tcx>) -> Self {
|
||||
if let PredicateKind::Clause(ClauseKind::Trait(TraitPredicate { trait_ref, constness, polarity })) = self.kind().skip_binder()
|
||||
&& constness != BoundConstness::NotConst
|
||||
{
|
||||
self = tcx.mk_predicate(self.kind().rebind(PredicateKind::Clause(ClauseKind::Trait(TraitPredicate {
|
||||
trait_ref,
|
||||
constness: BoundConstness::NotConst,
|
||||
polarity,
|
||||
}))));
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx), ret)]
|
||||
pub fn is_coinductive(self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
match self.kind().skip_binder() {
|
||||
@ -629,10 +614,6 @@ impl<'tcx> Clause<'tcx> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn without_const(self, tcx: TyCtxt<'tcx>) -> Clause<'tcx> {
|
||||
self.as_predicate().without_const(tcx).expect_clause()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
@ -852,8 +833,6 @@ impl<'tcx> Clause<'tcx> {
|
||||
pub struct TraitPredicate<'tcx> {
|
||||
pub trait_ref: TraitRef<'tcx>,
|
||||
|
||||
pub constness: BoundConstness,
|
||||
|
||||
/// If polarity is Positive: we are proving that the trait is implemented.
|
||||
///
|
||||
/// If polarity is Negative: we are proving that a negative impl of this trait
|
||||
@ -878,24 +857,6 @@ impl<'tcx> TraitPredicate<'tcx> {
|
||||
pub fn self_ty(self) -> Ty<'tcx> {
|
||||
self.trait_ref.self_ty()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_const_if_const(self) -> bool {
|
||||
self.constness == BoundConstness::ConstIfConst
|
||||
}
|
||||
|
||||
pub fn is_constness_satisfied_by(self, constness: hir::Constness) -> bool {
|
||||
match (self.constness, constness) {
|
||||
(BoundConstness::NotConst, _)
|
||||
| (BoundConstness::ConstIfConst, hir::Constness::Const) => true,
|
||||
(BoundConstness::ConstIfConst, hir::Constness::NotConst) => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn without_const(mut self) -> Self {
|
||||
self.constness = BoundConstness::NotConst;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||
@ -908,11 +869,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||
self.map_bound(|trait_ref| trait_ref.self_ty())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn is_const_if_const(self) -> bool {
|
||||
self.skip_binder().is_const_if_const()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn polarity(self) -> ImplPolarity {
|
||||
self.skip_binder().polarity
|
||||
@ -1287,7 +1243,7 @@ impl<'tcx> ToPredicate<'tcx> for TraitRef<'tcx> {
|
||||
impl<'tcx> ToPredicate<'tcx, TraitPredicate<'tcx>> for TraitRef<'tcx> {
|
||||
#[inline(always)]
|
||||
fn to_predicate(self, _tcx: TyCtxt<'tcx>) -> TraitPredicate<'tcx> {
|
||||
self.without_const()
|
||||
TraitPredicate { trait_ref: self, polarity: ImplPolarity::Positive }
|
||||
}
|
||||
}
|
||||
|
||||
@ -1328,7 +1284,6 @@ impl<'tcx> ToPredicate<'tcx, PolyTraitPredicate<'tcx>> for Binder<'tcx, TraitRef
|
||||
fn to_predicate(self, _: TyCtxt<'tcx>) -> PolyTraitPredicate<'tcx> {
|
||||
self.map_bound(|trait_ref| TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
})
|
||||
}
|
||||
@ -1826,24 +1781,6 @@ impl<'tcx> ParamEnv<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME(ecstaticmorse): Audit all occurrences of `without_const().to_predicate(tcx)` to ensure that
|
||||
// the constness of trait bounds is being propagated correctly.
|
||||
impl<'tcx> PolyTraitRef<'tcx> {
|
||||
#[inline]
|
||||
pub fn with_constness(self, constness: BoundConstness) -> PolyTraitPredicate<'tcx> {
|
||||
self.map_bound(|trait_ref| ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn without_const(self) -> PolyTraitPredicate<'tcx> {
|
||||
self.with_constness(BoundConstness::NotConst)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
|
||||
#[derive(HashStable, Lift)]
|
||||
pub struct ParamEnvAnd<'tcx, T> {
|
||||
|
@ -2806,10 +2806,7 @@ define_print_and_forward_display! {
|
||||
}
|
||||
|
||||
TraitPredPrintModifiersAndPath<'tcx> {
|
||||
if let ty::BoundConstness::ConstIfConst = self.0.constness {
|
||||
p!("~const ")
|
||||
}
|
||||
|
||||
// FIXME(effects) print `~const` here
|
||||
if let ty::ImplPolarity::Negative = self.0.polarity {
|
||||
p!("!")
|
||||
}
|
||||
@ -2843,9 +2840,7 @@ define_print_and_forward_display! {
|
||||
|
||||
ty::TraitPredicate<'tcx> {
|
||||
p!(print(self.trait_ref.self_ty()), ": ");
|
||||
if let ty::BoundConstness::ConstIfConst = self.constness && cx.tcx().features().const_trait_impl {
|
||||
p!("~const ");
|
||||
}
|
||||
// FIXME(effects) print `~const` here
|
||||
if let ty::ImplPolarity::Negative = self.polarity {
|
||||
p!("!");
|
||||
}
|
||||
|
@ -826,7 +826,6 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
|
||||
) -> RelateResult<'tcx, ty::TraitPredicate<'tcx>> {
|
||||
Ok(ty::TraitPredicate {
|
||||
trait_ref: relation.relate(a.trait_ref, b.trait_ref)?,
|
||||
constness: relation.relate(a.constness, b.constness)?,
|
||||
polarity: relation.relate(a.polarity, b.polarity)?,
|
||||
})
|
||||
}
|
||||
|
@ -172,9 +172,7 @@ impl fmt::Debug for ty::ParamConst {
|
||||
|
||||
impl<'tcx> fmt::Debug for ty::TraitPredicate<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
if let ty::BoundConstness::ConstIfConst = self.constness {
|
||||
write!(f, "~const ")?;
|
||||
}
|
||||
// FIXME(effects) printing?
|
||||
write!(f, "TraitPredicate({:?}, polarity:{:?})", self.trait_ref, self.polarity)
|
||||
}
|
||||
}
|
||||
|
@ -722,7 +722,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
|
||||
use crate::ty::ToPredicate;
|
||||
match self.skip_binder() {
|
||||
ExistentialPredicate::Trait(tr) => {
|
||||
self.rebind(tr).with_self_ty(tcx, self_ty).without_const().to_predicate(tcx)
|
||||
self.rebind(tr).with_self_ty(tcx, self_ty).to_predicate(tcx)
|
||||
}
|
||||
ExistentialPredicate::Projection(p) => {
|
||||
self.rebind(p.with_self_ty(tcx, self_ty)).to_predicate(tcx)
|
||||
@ -737,7 +737,7 @@ impl<'tcx> PolyExistentialPredicate<'tcx> {
|
||||
let err_args = ty::GenericArgs::extend_with_error(tcx, did, &[self_ty.into()]);
|
||||
ty::TraitRef::new(tcx, did, err_args)
|
||||
};
|
||||
self.rebind(trait_ref).without_const().to_predicate(tcx)
|
||||
self.rebind(trait_ref).to_predicate(tcx)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -869,18 +869,6 @@ impl<'tcx> TraitRef<'tcx> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Converts this trait ref to a trait predicate with a given `constness` and a positive polarity.
|
||||
#[inline]
|
||||
pub fn with_constness(self, constness: ty::BoundConstness) -> ty::TraitPredicate<'tcx> {
|
||||
ty::TraitPredicate { trait_ref: self, constness, polarity: ty::ImplPolarity::Positive }
|
||||
}
|
||||
|
||||
/// Converts this trait ref to a trait predicate without `const` and a positive polarity.
|
||||
#[inline]
|
||||
pub fn without_const(self) -> ty::TraitPredicate<'tcx> {
|
||||
self.with_constness(ty::BoundConstness::NotConst)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn self_ty(&self) -> Ty<'tcx> {
|
||||
self.args.type_at(0)
|
||||
|
@ -147,7 +147,7 @@ where
|
||||
|
||||
fn visit_clause(&mut self, clause: ty::Clause<'tcx>) -> ControlFlow<V::BreakTy> {
|
||||
match clause.kind().skip_binder() {
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, constness: _, polarity: _ }) => {
|
||||
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity: _ }) => {
|
||||
self.visit_trait(trait_ref)
|
||||
}
|
||||
ty::ClauseKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
|
||||
|
@ -72,7 +72,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
cause: traits::ObligationCause::dummy(),
|
||||
param_env,
|
||||
recursion_depth: 0,
|
||||
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx),
|
||||
predicate: ty::Binder::dummy(trait_ref).to_predicate(self.tcx),
|
||||
};
|
||||
self.evaluate_obligation(&obligation).unwrap_or(traits::EvaluationResult::EvaluatedToErr)
|
||||
}
|
||||
|
@ -727,7 +727,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
self.tcx(),
|
||||
ty::TraitPredicate {
|
||||
trait_ref: self_trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
},
|
||||
);
|
||||
|
@ -97,7 +97,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
orig_env,
|
||||
ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: if polarity {
|
||||
ImplPolarity::Positive
|
||||
} else {
|
||||
@ -260,7 +259,6 @@ impl<'tcx> AutoTraitFinder<'tcx> {
|
||||
predicates.push_back(ty::Binder::dummy(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::new(infcx.tcx, trait_did, [ty]),
|
||||
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
// Auto traits are positive
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}));
|
||||
|
@ -97,7 +97,7 @@ impl<'a, 'tcx> ObligationCtxt<'a, 'tcx> {
|
||||
cause,
|
||||
recursion_depth: 0,
|
||||
param_env,
|
||||
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
|
||||
predicate: ty::Binder::dummy(trait_ref).to_predicate(tcx),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -100,7 +100,6 @@ pub trait InferCtxtExt<'tcx> {
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
constness: ty::BoundConstness,
|
||||
polarity: ty::ImplPolarity,
|
||||
) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()>;
|
||||
}
|
||||
@ -356,7 +355,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
&self,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
ty: ty::Binder<'tcx, Ty<'tcx>>,
|
||||
constness: ty::BoundConstness,
|
||||
polarity: ty::ImplPolarity,
|
||||
) -> Result<(ty::ClosureKind, ty::Binder<'tcx, Ty<'tcx>>), ()> {
|
||||
self.commit_if_ok(|_| {
|
||||
@ -372,12 +370,13 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
|
||||
span: DUMMY_SP,
|
||||
kind: TypeVariableOriginKind::MiscVariable,
|
||||
});
|
||||
// FIXME(effects)
|
||||
let trait_ref = ty::TraitRef::new(self.tcx, trait_def_id, [ty.skip_binder(), var]);
|
||||
let obligation = Obligation::new(
|
||||
self.tcx,
|
||||
ObligationCause::dummy(),
|
||||
param_env,
|
||||
ty.rebind(ty::TraitPredicate { trait_ref, constness, polarity }),
|
||||
ty.rebind(ty::TraitPredicate { trait_ref, polarity }),
|
||||
);
|
||||
let ocx = ObligationCtxt::new(self);
|
||||
ocx.register_obligation(obligation);
|
||||
@ -689,8 +688,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
let trait_predicate = bound_predicate.rebind(trait_predicate);
|
||||
let trait_predicate = self.resolve_vars_if_possible(trait_predicate);
|
||||
|
||||
let predicate_is_const = ty::BoundConstness::ConstIfConst
|
||||
== trait_predicate.skip_binder().constness;
|
||||
// FIXME(effects)
|
||||
let predicate_is_const = false;
|
||||
|
||||
if self.tcx.sess.has_errors().is_some()
|
||||
&& trait_predicate.references_error()
|
||||
@ -1909,9 +1908,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
.all_impls(trait_pred.def_id())
|
||||
.filter_map(|def_id| {
|
||||
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative
|
||||
|| !trait_pred
|
||||
.skip_binder()
|
||||
.is_constness_satisfied_by(self.tcx.constness(def_id))
|
||||
|| !self.tcx.is_user_visible_dep(def_id.krate)
|
||||
{
|
||||
return None;
|
||||
@ -2996,7 +2992,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
&& let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
|
||||
obligation.param_env,
|
||||
trait_ref.self_ty(),
|
||||
trait_predicate.skip_binder().constness,
|
||||
trait_predicate.skip_binder().polarity,
|
||||
)
|
||||
{
|
||||
@ -3099,14 +3094,15 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
fn maybe_add_note_for_unsatisfied_const(
|
||||
&self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
||||
err: &mut Diagnostic,
|
||||
span: Span,
|
||||
_obligation: &PredicateObligation<'tcx>,
|
||||
_trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
_trait_predicate: &ty::PolyTraitPredicate<'tcx>,
|
||||
_err: &mut Diagnostic,
|
||||
_span: Span,
|
||||
) -> UnsatisfiedConst {
|
||||
let mut unsatisfied_const = UnsatisfiedConst(false);
|
||||
if trait_predicate.is_const_if_const() {
|
||||
let unsatisfied_const = UnsatisfiedConst(false);
|
||||
// FIXME(effects)
|
||||
/* if trait_predicate.is_const_if_const() {
|
||||
let non_const_predicate = trait_ref.without_const();
|
||||
let non_const_obligation = Obligation {
|
||||
cause: obligation.cause.clone(),
|
||||
@ -3126,7 +3122,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
} */
|
||||
unsatisfied_const
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
|
||||
def_id: DefId,
|
||||
) -> bool {
|
||||
let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
|
||||
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref.without_const())
|
||||
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref)
|
||||
}
|
||||
|
||||
/// FIXME(@lcnr): this function doesn't seem right and shouldn't exist?
|
||||
|
@ -574,7 +574,6 @@ fn virtual_call_violation_for_method<'tcx>(
|
||||
// implement auto traits if the underlying type does as well.
|
||||
if let ty::ClauseKind::Trait(ty::TraitPredicate {
|
||||
trait_ref: pred_trait_ref,
|
||||
constness: ty::BoundConstness::NotConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}) = pred.kind().skip_binder()
|
||||
&& pred_trait_ref.self_ty() == tcx.types.self_param
|
||||
|
@ -1306,7 +1306,7 @@ fn normalize_to_error<'a, 'tcx>(
|
||||
cause,
|
||||
recursion_depth: depth,
|
||||
param_env,
|
||||
predicate: trait_ref.without_const().to_predicate(selcx.tcx()),
|
||||
predicate: trait_ref.to_predicate(selcx.tcx()),
|
||||
};
|
||||
let tcx = selcx.infcx.tcx;
|
||||
let new_value = selcx.infcx.next_ty_var(TypeVariableOrigin {
|
||||
@ -1867,8 +1867,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
||||
if selcx.infcx.predicate_must_hold_modulo_regions(
|
||||
&obligation.with(
|
||||
selcx.tcx(),
|
||||
ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty])
|
||||
.without_const(),
|
||||
ty::TraitRef::from_lang_item(selcx.tcx(), LangItem::Sized, obligation.cause.span(),[self_ty]),
|
||||
),
|
||||
) =>
|
||||
{
|
||||
@ -2152,8 +2151,7 @@ fn confirm_builtin_candidate<'cx, 'tcx>(
|
||||
LangItem::Sized,
|
||||
obligation.cause.span(),
|
||||
[self_ty],
|
||||
)
|
||||
.without_const();
|
||||
);
|
||||
obligations.push(obligation.with(tcx, sized_predicate));
|
||||
}
|
||||
(metadata_ty.into(), obligations)
|
||||
|
@ -154,9 +154,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
.infcx
|
||||
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
|
||||
|
||||
candidates
|
||||
.vec
|
||||
.extend(result.into_iter().map(|(idx, constness)| ProjectionCandidate(idx, constness)));
|
||||
// FIXME(effects) proper constness needed?
|
||||
candidates.vec.extend(
|
||||
result.into_iter().map(|idx| ProjectionCandidate(idx, ty::BoundConstness::NotConst)),
|
||||
);
|
||||
}
|
||||
|
||||
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
|
||||
|
@ -59,7 +59,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
ParamCandidate(param) => {
|
||||
let obligations =
|
||||
self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
|
||||
ImplSource::Param(param.skip_binder().constness, obligations)
|
||||
// FIXME(effects)
|
||||
ImplSource::Param(ty::BoundConstness::NotConst, obligations)
|
||||
}
|
||||
|
||||
ImplCandidate(impl_def_id) => {
|
||||
@ -128,14 +129,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
subobligation.set_depth_from_parent(obligation.recursion_depth);
|
||||
}
|
||||
|
||||
if !obligation.predicate.is_const_if_const() {
|
||||
// normalize nested predicates according to parent predicate's constness.
|
||||
impl_src = impl_src.map(|mut o| {
|
||||
o.predicate = o.predicate.without_const(self.tcx());
|
||||
o
|
||||
});
|
||||
}
|
||||
|
||||
Ok(impl_src)
|
||||
}
|
||||
|
||||
@ -1305,6 +1298,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// If we have a projection type, make sure to normalize it so we replace it
|
||||
// with a fresh infer variable
|
||||
ty::Alias(ty::Projection | ty::Inherent, ..) => {
|
||||
// FIXME(effects) this needs constness
|
||||
let predicate = normalize_with_depth_to(
|
||||
self,
|
||||
obligation.param_env,
|
||||
@ -1317,7 +1311,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
cause.span,
|
||||
[nested_ty],
|
||||
),
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
}),
|
||||
&mut nested,
|
||||
@ -1336,6 +1329,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// since it's either not `const Drop` (and we raise an error during selection),
|
||||
// or it's an ADT (and we need to check for a custom impl during selection)
|
||||
_ => {
|
||||
// FIXME(effects) this needs constness
|
||||
let predicate = self_ty.rebind(ty::TraitPredicate {
|
||||
trait_ref: ty::TraitRef::from_lang_item(
|
||||
self.tcx(),
|
||||
@ -1343,7 +1337,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
cause.span,
|
||||
[nested_ty],
|
||||
),
|
||||
constness: ty::BoundConstness::ConstIfConst,
|
||||
polarity: ty::ImplPolarity::Positive,
|
||||
});
|
||||
|
||||
|
@ -1583,7 +1583,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
fn match_projection_obligation_against_definition_bounds(
|
||||
&mut self,
|
||||
obligation: &PolyTraitObligation<'tcx>,
|
||||
) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> {
|
||||
) -> smallvec::SmallVec<[usize; 2]> {
|
||||
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
|
||||
let placeholder_trait_predicate =
|
||||
self.infcx.instantiate_binder_with_placeholders(poly_trait_predicate);
|
||||
@ -1632,7 +1632,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
_ => false,
|
||||
}
|
||||
}) {
|
||||
return Some((idx, pred.constness));
|
||||
return Some(idx);
|
||||
}
|
||||
}
|
||||
None
|
||||
@ -1820,7 +1820,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
(ParamCandidate(other), ParamCandidate(victim)) => {
|
||||
let same_except_bound_vars = other.skip_binder().trait_ref
|
||||
== victim.skip_binder().trait_ref
|
||||
&& other.skip_binder().constness == victim.skip_binder().constness
|
||||
&& other.skip_binder().polarity == victim.skip_binder().polarity
|
||||
&& !other.skip_binder().trait_ref.has_escaping_bound_vars();
|
||||
if same_except_bound_vars {
|
||||
@ -1830,12 +1829,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
// probably best characterized as a "hack", since we might prefer to just do our
|
||||
// best to *not* create essentially duplicate candidates in the first place.
|
||||
DropVictim::drop_if(other.bound_vars().len() <= victim.bound_vars().len())
|
||||
} else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref
|
||||
&& victim.skip_binder().constness == ty::BoundConstness::NotConst
|
||||
&& other.skip_binder().polarity == victim.skip_binder().polarity
|
||||
{
|
||||
// Drop otherwise equivalent non-const candidates in favor of const candidates.
|
||||
DropVictim::Yes
|
||||
} else {
|
||||
DropVictim::No
|
||||
}
|
||||
|
@ -500,16 +500,12 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti
|
||||
let mut pretty_predicates =
|
||||
Vec::with_capacity(predicates.len() + types_without_default_bounds.len());
|
||||
|
||||
for (mut p, _) in predicates {
|
||||
for (p, _) in predicates {
|
||||
if let Some(poly_trait_ref) = p.as_trait_clause() {
|
||||
if Some(poly_trait_ref.def_id()) == sized_trait {
|
||||
types_without_default_bounds.remove(&poly_trait_ref.self_ty().skip_binder());
|
||||
continue;
|
||||
}
|
||||
|
||||
if ty::BoundConstness::ConstIfConst == poly_trait_ref.skip_binder().constness {
|
||||
p = p.without_const(tcx);
|
||||
}
|
||||
}
|
||||
pretty_predicates.push(p.to_string());
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
||||
fn expand(&mut self, item: &TraitAliasExpansionInfo<'tcx>) -> bool {
|
||||
let tcx = self.tcx;
|
||||
let trait_ref = item.trait_ref();
|
||||
let pred = trait_ref.without_const().to_predicate(tcx);
|
||||
let pred = trait_ref.to_predicate(tcx);
|
||||
|
||||
debug!("expand_trait_aliases: trait_ref={:?}", trait_ref);
|
||||
|
||||
@ -113,9 +113,13 @@ impl<'tcx> TraitAliasExpander<'tcx> {
|
||||
|
||||
// Don't recurse if this trait alias is already on the stack for the DFS search.
|
||||
let anon_pred = anonymize_predicate(tcx, pred);
|
||||
if item.path.iter().rev().skip(1).any(|&(tr, _)| {
|
||||
anonymize_predicate(tcx, tr.without_const().to_predicate(tcx)) == anon_pred
|
||||
}) {
|
||||
if item
|
||||
.path
|
||||
.iter()
|
||||
.rev()
|
||||
.skip(1)
|
||||
.any(|&(tr, _)| anonymize_predicate(tcx, tr.to_predicate(tcx)) == anon_pred)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ fn prepare_vtable_segments_inner<'tcx, T>(
|
||||
|
||||
let mut emit_vptr_on_new_entry = false;
|
||||
let mut visited = PredicateSet::new(tcx);
|
||||
let predicate = trait_ref.without_const().to_predicate(tcx);
|
||||
let predicate = trait_ref.to_predicate(tcx);
|
||||
let mut stack: SmallVec<[(ty::PolyTraitRef<'tcx>, _, _); 5]> =
|
||||
smallvec![(trait_ref, emit_vptr_on_new_entry, maybe_iter(None))];
|
||||
visited.insert(predicate);
|
||||
|
@ -348,11 +348,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// if the trait predicate is not const, the wf obligations should not be const as well.
|
||||
let obligations = if trait_pred.constness == ty::BoundConstness::NotConst {
|
||||
self.nominal_obligations_without_const(trait_ref.def_id, trait_ref.args)
|
||||
} else {
|
||||
self.nominal_obligations(trait_ref.def_id, trait_ref.args)
|
||||
};
|
||||
let obligations = self.nominal_obligations(trait_ref.def_id, trait_ref.args);
|
||||
|
||||
debug!("compute_trait_pred obligations {:?}", obligations);
|
||||
let param_env = self.param_env;
|
||||
@ -445,8 +441,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
// `i32: Clone`
|
||||
// `i32: Copy`
|
||||
// ]
|
||||
// Projection types do not require const predicates.
|
||||
let obligations = self.nominal_obligations_without_const(data.def_id, data.args);
|
||||
let obligations = self.nominal_obligations(data.def_id, data.args);
|
||||
self.out.extend(obligations);
|
||||
|
||||
self.compute_projection_args(data.args);
|
||||
@ -472,8 +467,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
self.recursion_depth,
|
||||
&mut self.out,
|
||||
);
|
||||
// Inherent projection types do not require const predicates.
|
||||
let obligations = self.nominal_obligations_without_const(data.def_id, args);
|
||||
let obligations = self.nominal_obligations(data.def_id, args);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
@ -516,7 +510,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
cause,
|
||||
self.recursion_depth,
|
||||
self.param_env,
|
||||
ty::Binder::dummy(trait_ref).without_const(),
|
||||
ty::Binder::dummy(trait_ref),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -667,7 +661,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
}
|
||||
|
||||
ty::FnDef(did, args) => {
|
||||
let obligations = self.nominal_obligations_without_const(did, args);
|
||||
let obligations = self.nominal_obligations(did, args);
|
||||
self.out.extend(obligations);
|
||||
}
|
||||
|
||||
@ -822,11 +816,10 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn nominal_obligations_inner(
|
||||
fn nominal_obligations(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
remap_constness: bool,
|
||||
) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||
let predicates = self.tcx().predicates_of(def_id);
|
||||
let mut origins = vec![def_id; predicates.predicates.len()];
|
||||
@ -841,16 +834,13 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
debug_assert_eq!(predicates.predicates.len(), origins.len());
|
||||
|
||||
iter::zip(predicates, origins.into_iter().rev())
|
||||
.map(|((mut pred, span), origin_def_id)| {
|
||||
.map(|((pred, span), origin_def_id)| {
|
||||
let code = if span.is_dummy() {
|
||||
traits::ItemObligation(origin_def_id)
|
||||
} else {
|
||||
traits::BindingObligation(origin_def_id, span)
|
||||
};
|
||||
let cause = self.cause(code);
|
||||
if remap_constness {
|
||||
pred = pred.without_const(self.tcx());
|
||||
}
|
||||
traits::Obligation::with_depth(
|
||||
self.tcx(),
|
||||
cause,
|
||||
@ -863,22 +853,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn nominal_obligations(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||
self.nominal_obligations_inner(def_id, args, false)
|
||||
}
|
||||
|
||||
fn nominal_obligations_without_const(
|
||||
&mut self,
|
||||
def_id: DefId,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Vec<traits::PredicateObligation<'tcx>> {
|
||||
self.nominal_obligations_inner(def_id, args, true)
|
||||
}
|
||||
|
||||
fn from_object_ty(
|
||||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
|
@ -370,9 +370,8 @@ fn clean_poly_trait_predicate<'tcx>(
|
||||
cx: &mut DocContext<'tcx>,
|
||||
) -> Option<WherePredicate> {
|
||||
// `T: ~const Destruct` is hidden because `T: Destruct` is a no-op.
|
||||
if pred.skip_binder().constness == ty::BoundConstness::ConstIfConst
|
||||
&& Some(pred.skip_binder().def_id()) == cx.tcx.lang_items().destruct_trait()
|
||||
{
|
||||
// FIXME(effects) check constness
|
||||
if Some(pred.skip_binder().def_id()) == cx.tcx.lang_items().destruct_trait() {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::traits::Reveal;
|
||||
use rustc_middle::ty::{
|
||||
self, BoundConstness, ClauseKind, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv,
|
||||
self, ClauseKind, GenericArgKind, GenericParamDefKind, ImplPolarity, ParamEnv,
|
||||
ToPredicate, TraitPredicate, Ty, TyCtxt,
|
||||
};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -523,7 +523,6 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
|
||||
if let ClauseKind::Trait(p) = p.kind().skip_binder()
|
||||
&& p.trait_ref.def_id == eq_trait_id
|
||||
&& let ty::Param(self_ty) = p.trait_ref.self_ty().kind()
|
||||
&& p.constness == BoundConstness::NotConst
|
||||
{
|
||||
// Flag types which already have an `Eq` bound.
|
||||
params[self_ty.index as usize].1 = false;
|
||||
@ -535,7 +534,6 @@ fn param_env_for_derived_eq(tcx: TyCtxt<'_>, did: DefId, eq_trait_id: DefId) ->
|
||||
params.iter().filter(|&&(_, needs_eq)| needs_eq).map(|&(param, _)| {
|
||||
ClauseKind::Trait(TraitPredicate {
|
||||
trait_ref: ty::TraitRef::new(tcx, eq_trait_id, [tcx.mk_param_from_def(param)]),
|
||||
constness: BoundConstness::NotConst,
|
||||
polarity: ImplPolarity::Positive,
|
||||
})
|
||||
.to_predicate(tcx)
|
||||
|
@ -10,7 +10,7 @@ use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPat
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, BoundConstness, ClosureArgs, ClosureKind, EarlyBinder, FnSig, GenericArg, GenericArgKind,
|
||||
self, Binder, ClosureArgs, ClosureKind, EarlyBinder, FnSig, GenericArg, GenericArgKind,
|
||||
GenericArgsRef, ImplPolarity, List, Region, RegionKind, Ty, TypeVisitableExt, TypeckResults,
|
||||
};
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
@ -171,7 +171,6 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
|
||||
= cx.tcx.infer_ctxt().build().type_implements_fn_trait(
|
||||
cx.param_env,
|
||||
Binder::bind_with_vars(callee_ty_adjusted, List::empty()),
|
||||
BoundConstness::NotConst,
|
||||
ImplPolarity::Positive,
|
||||
) && path_to_local(callee)
|
||||
.map_or(
|
||||
|
@ -16,7 +16,7 @@ use rustc_middle::mir::{
|
||||
};
|
||||
use rustc_middle::traits::{ImplSource, ObligationCause, BuiltinImplSource};
|
||||
use rustc_middle::ty::adjustment::PointerCoercion;
|
||||
use rustc_middle::ty::{self, BoundConstness, GenericArgKind, TraitRef, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt};
|
||||
use rustc_semver::RustcVersion;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::Span;
|
||||
@ -399,11 +399,12 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
|
||||
return true;
|
||||
}
|
||||
|
||||
// FIXME(effects) constness
|
||||
let obligation = Obligation::new(
|
||||
tcx,
|
||||
ObligationCause::dummy_with_span(body.span),
|
||||
ConstCx::new(tcx, body).param_env,
|
||||
TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]).with_constness(BoundConstness::ConstIfConst),
|
||||
TraitRef::from_lang_item(tcx, LangItem::Destruct, body.span, [ty]),
|
||||
);
|
||||
|
||||
let infcx = tcx.infer_ctxt().build();
|
||||
|
@ -267,7 +267,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
|
||||
cause: ObligationCause::dummy(),
|
||||
param_env,
|
||||
recursion_depth: 0,
|
||||
predicate: ty::Binder::dummy(trait_ref).without_const().to_predicate(tcx),
|
||||
predicate: ty::Binder::dummy(trait_ref).to_predicate(tcx),
|
||||
};
|
||||
infcx
|
||||
.evaluate_obligation(&obligation)
|
||||
|
@ -1,5 +1,6 @@
|
||||
// compile-flags: -Zmir-opt-level=0
|
||||
// run-pass
|
||||
// known-bug: #110395
|
||||
// FIXME run-pass
|
||||
|
||||
#![feature(const_float_bits_conv)]
|
||||
#![feature(const_float_classify)]
|
||||
|
11
tests/ui/consts/const-float-classify.stderr
Normal file
11
tests/ui/consts/const-float-classify.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<A as MyEq<B>>::eq` in constant functions
|
||||
--> $DIR/const-float-classify.rs:31:7
|
||||
|
|
||||
LL | x.eq(y)
|
||||
| ^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -7,12 +7,22 @@ LL | #![feature(const_trait_impl, generic_const_exprs)]
|
||||
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0080]: evaluation of `foo::<()>::{constant#0}` failed
|
||||
error[E0015]: cannot call non-const fn `<T as Tr>::a` in constants
|
||||
--> $DIR/constifconst-call-in-const-position.rs:17:9
|
||||
|
|
||||
LL | [0; T::a()]
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const fn `<T as Tr>::a` in constants
|
||||
--> $DIR/constifconst-call-in-const-position.rs:16:38
|
||||
|
|
||||
LL | const fn foo<T: ~const Tr>() -> [u8; T::a()] {
|
||||
| ^^^^^^ calling non-const function `<() as Tr>::a`
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
error: aborting due to 2 previous errors; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
@ -20,6 +20,7 @@ impl<T> Opt<T> {
|
||||
match self {
|
||||
Opt::Some(t) => t,
|
||||
Opt::None => f(),
|
||||
//~^ ERROR cannot call
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,15 @@
|
||||
error[E0015]: cannot call non-const closure in constant functions
|
||||
--> $DIR/unstable-const-fn-in-libcore.rs:22:26
|
||||
|
|
||||
LL | Opt::None => f(),
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn unwrap_or_else<F: ~const FnOnce() -> T + ~const std::ops::FnOnce<()>>(self, f: F) -> T {
|
||||
| +++++++++++++++++++++++++++++
|
||||
|
||||
error[E0493]: destructor of `F` cannot be evaluated at compile-time
|
||||
--> $DIR/unstable-const-fn-in-libcore.rs:17:60
|
||||
|
|
||||
@ -16,6 +28,7 @@ LL | const fn unwrap_or_else<F: ~const FnOnce() -> T>(self, f: F) -> T {
|
||||
LL | }
|
||||
| - value is dropped here
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0493`.
|
||||
Some errors have detailed explanations: E0015, E0493.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -1,4 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME check-pass
|
||||
|
||||
// Test that we can call methods from const trait impls inside of generic const items.
|
||||
|
||||
|
11
tests/ui/generic-const-items/const-trait-impl.stderr
Normal file
11
tests/ui/generic-const-items/const-trait-impl.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Create>::create` in constants
|
||||
--> $DIR/const-trait-impl.rs:11:37
|
||||
|
|
||||
LL | const CREATE<T: ~const Create>: T = T::create();
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,3 +1,15 @@
|
||||
error[E0015]: cannot call non-const closure in constant functions
|
||||
--> $DIR/normalize-tait-in-const.rs:26:5
|
||||
|
|
||||
LL | fun(filter_positive());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn with_positive<F: ~const for<'a> Fn(&'a Alias<'a>) + ~const Destruct + ~const std::ops::Fn<(&Alias<'_>,)>>(fun: F) {
|
||||
| ++++++++++++++++++++++++++++++++++++
|
||||
|
||||
error[E0493]: destructor of `F` cannot be evaluated at compile-time
|
||||
--> $DIR/normalize-tait-in-const.rs:25:79
|
||||
|
|
||||
@ -7,6 +19,7 @@ LL | fun(filter_positive());
|
||||
LL | }
|
||||
| - value is dropped here
|
||||
|
||||
error: aborting due to previous error
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0493`.
|
||||
Some errors have detailed explanations: E0015, E0493.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -1,4 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<<T as Foo>::Assoc as Foo>::foo` in constant functions
|
||||
--> $DIR/assoc-type-const-bound-usage.rs:12:5
|
||||
|
|
||||
LL | <T as Foo>::Assoc::foo();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,21 +1,15 @@
|
||||
error[E0080]: evaluation of constant value failed
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
|
|
||||
= note: calling non-const function `<() as Tr>::a`
|
||||
|
|
||||
note: inside `<fn(()) -> i32 {<() as Tr>::a} as FnOnce<((),)>>::call_once - shim(fn(()) -> i32 {<() as Tr>::a})`
|
||||
--> $SRC_DIR/core/src/ops/function.rs:LL:COL
|
||||
note: inside `need_const_closure::<fn(()) -> i32 {<() as Tr>::a}>`
|
||||
error[E0015]: cannot call non-const closure in constant functions
|
||||
--> $DIR/const-closure-trait-method-fail.rs:15:5
|
||||
|
|
||||
LL | x(())
|
||||
| ^^^^^
|
||||
note: inside `_`
|
||||
--> $DIR/const-closure-trait-method-fail.rs:18:23
|
||||
|
|
||||
LL | const _: () = assert!(need_const_closure(Tr::a) == 42);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32 + ~const std::ops::FnOnce<((),)>>(x: T) -> i32 {
|
||||
| ++++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0080`.
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
@ -1,4 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
|
@ -0,0 +1,15 @@
|
||||
error[E0015]: cannot call non-const closure in constant functions
|
||||
--> $DIR/const-closure-trait-method.rs:15:5
|
||||
|
|
||||
LL | x(())
|
||||
| ^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn need_const_closure<T: ~const FnOnce(()) -> i32 + ~const std::ops::FnOnce<((),)>>(x: T) -> i32 {
|
||||
| ++++++++++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,4 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
|
@ -0,0 +1,39 @@
|
||||
error[E0015]: cannot call non-const closure in constant functions
|
||||
--> $DIR/const-closures.rs:12:5
|
||||
|
|
||||
LL | f() * 7
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | F: ~const FnOnce() -> u8 + ~const std::ops::Fn<()>,
|
||||
| +++++++++++++++++++++++++
|
||||
|
||||
error[E0015]: cannot call non-const closure in constant functions
|
||||
--> $DIR/const-closures.rs:24:5
|
||||
|
|
||||
LL | f() + f()
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn answer<F: ~const Fn() -> u8 + ~const std::ops::Fn<()>>(f: &F) -> u8 {
|
||||
| +++++++++++++++++++++++++
|
||||
|
||||
error[E0015]: cannot call non-const closure in constant functions
|
||||
--> $DIR/const-closures.rs:24:11
|
||||
|
|
||||
LL | f() + f()
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn answer<F: ~const Fn() -> u8 + ~const std::ops::Fn<()>>(f: &F) -> u8 {
|
||||
| +++++++++++++++++++++++++
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,3 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
|
||||
--> $DIR/const-drop-fail-2.rs:25:9
|
||||
|
|
||||
LL | T::a();
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0493]: destructor of `T` cannot be evaluated at compile-time
|
||||
--> $DIR/const-drop-fail-2.rs:29:36
|
||||
|
|
||||
@ -6,6 +14,15 @@ LL | const fn check<T: ~const Destruct>(_: T) {}
|
||||
| |
|
||||
| the destructor for this type cannot be evaluated in constant functions
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
|
||||
--> $DIR/const-drop-fail-2.rs:39:9
|
||||
|
|
||||
LL | T::a();
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
For more information about this error, try `rustc --explain E0493`.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0493.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -14,6 +14,15 @@ LL | let _ = S(&mut c);
|
||||
| |
|
||||
| the destructor for this type cannot be evaluated in constant functions
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
|
||||
--> $DIR/const-drop.rs:70:13
|
||||
|
|
||||
LL | T::foo();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
For more information about this error, try `rustc --explain E0493`.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0493.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -14,6 +14,15 @@ LL | let _ = S(&mut c);
|
||||
| |
|
||||
| the destructor for this type cannot be evaluated in constant functions
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
|
||||
--> $DIR/const-drop.rs:70:13
|
||||
|
|
||||
LL | T::foo();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
For more information about this error, try `rustc --explain E0493`.
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0015, E0493.
|
||||
For more information about an error, try `rustc --explain E0015`.
|
||||
|
@ -13,7 +13,7 @@ const fn foo<T>() where T: ~const Tr {}
|
||||
pub trait Foo {
|
||||
fn foo() {
|
||||
foo::<()>();
|
||||
//FIXME ~^ ERROR the trait bound `(): ~const Tr` is not satisfied
|
||||
//FIXME ~^ ERROR the trait bound `(): Tr` is not satisfied
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
error[E0277]: the trait bound `(): ~const Tr` is not satisfied
|
||||
error[E0277]: the trait bound `(): Tr` is not satisfied
|
||||
--> $DIR/default-method-body-is-const-same-trait-ck.rs:8:12
|
||||
|
|
||||
LL | ().a()
|
||||
| ^ the trait `~const Tr` is not implemented for `()`
|
||||
| ^ the trait `Tr` is not implemented for `()`
|
||||
|
|
||||
= help: the trait `Tr` is implemented for `()`
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Tests that trait bounds on specializing trait impls must be `~const` if the
|
||||
// same bound is present on the default impl and is `~const` there.
|
||||
// known-bug: #110395
|
||||
// check-pass
|
||||
// FIXME(effects) ^ should error
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(rustc_attrs)]
|
||||
|
@ -1,14 +0,0 @@
|
||||
error: missing `~const` qualifier for specialization
|
||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:33:8
|
||||
|
|
||||
LL | T: Foo, //FIXME ~ ERROR missing `~const` qualifier
|
||||
| ^^^
|
||||
|
||||
error: missing `~const` qualifier for specialization
|
||||
--> $DIR/const-default-bound-non-const-specialized-bound.rs:53:8
|
||||
|
|
||||
LL | T: Foo,
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
@ -1,7 +1,8 @@
|
||||
// Tests that a const default trait impl can be specialized by another const
|
||||
// trait impl and that the specializing impl will be used during const-eval.
|
||||
|
||||
// run-pass
|
||||
// known-bug: #110395
|
||||
// FIXME run-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(min_specialization)]
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Value>::value` in constant functions
|
||||
--> $DIR/const-default-const-specialized.rs:16:5
|
||||
|
|
||||
LL | T::value()
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,7 +1,7 @@
|
||||
// Tests that a non-const default impl can be specialized by a const trait impl,
|
||||
// but that the default impl cannot be used in a const context.
|
||||
|
||||
// run-pass
|
||||
// known-bug: #110395
|
||||
// FIXME run-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(min_specialization)]
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Value>::value` in constant functions
|
||||
--> $DIR/non-const-default-const-specialized.rs:15:5
|
||||
|
|
||||
LL | T::value()
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -22,7 +22,7 @@ impl<T: ~const Spec> const A for T {
|
||||
|
||||
impl<T: Spec + Sup> A for T {
|
||||
//~^ ERROR: cannot specialize
|
||||
//~| ERROR: missing `~const` qualifier
|
||||
//FIXME(effects) ~| ERROR: missing `~const` qualifier
|
||||
fn a() -> u32 {
|
||||
3
|
||||
}
|
||||
|
@ -4,11 +4,5 @@ error: cannot specialize on const impl with non-const impl
|
||||
LL | impl<T: Spec + Sup> A for T {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: missing `~const` qualifier for specialization
|
||||
--> $DIR/specializing-constness.rs:23:9
|
||||
|
|
||||
LL | impl<T: Spec + Sup> A for T {
|
||||
| ^^^^
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,17 +1,17 @@
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/super-traits-fail-3.rs:12:19
|
||||
--> $DIR/super-traits-fail-3.rs:13:19
|
||||
|
|
||||
LL | trait Bar: ~const Foo {}
|
||||
| ^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/super-traits-fail-3.rs:12:19
|
||||
--> $DIR/super-traits-fail-3.rs:13:19
|
||||
|
|
||||
LL | trait Bar: ~const Foo {}
|
||||
| ^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/super-traits-fail-3.rs:16:24
|
||||
--> $DIR/super-traits-fail-3.rs:17:24
|
||||
|
|
||||
LL | const fn foo<T: ~const Bar>(x: &T) {
|
||||
| ^^^
|
||||
|
@ -1,11 +1,11 @@
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/super-traits-fail-3.rs:12:19
|
||||
--> $DIR/super-traits-fail-3.rs:13:19
|
||||
|
|
||||
LL | trait Bar: ~const Foo {}
|
||||
| ^^^
|
||||
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/super-traits-fail-3.rs:12:19
|
||||
--> $DIR/super-traits-fail-3.rs:13:19
|
||||
|
|
||||
LL | trait Bar: ~const Foo {}
|
||||
| ^^^
|
||||
|
@ -1,7 +1,8 @@
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
// revisions: yy yn ny nn
|
||||
//[yy] check-pass
|
||||
//[yy] known-bug: #110395
|
||||
//FIXME [yy] check-pass
|
||||
|
||||
#[cfg_attr(any(yy, yn), const_trait)]
|
||||
trait Foo {
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: ~const can only be applied to `#[const_trait]` traits
|
||||
--> $DIR/super-traits-fail-3.rs:16:24
|
||||
--> $DIR/super-traits-fail-3.rs:17:24
|
||||
|
|
||||
LL | const fn foo<T: ~const Bar>(x: &T) {
|
||||
| ^^^
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
|
||||
--> $DIR/super-traits-fail-3.rs:19:7
|
||||
|
|
||||
LL | x.a();
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,4 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
|
11
tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr
Normal file
11
tests/ui/rfcs/rfc-2632-const-trait-impl/super-traits.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
|
||||
--> $DIR/super-traits.rs:21:7
|
||||
|
|
||||
LL | t.a();
|
||||
| ^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -24,6 +24,7 @@ impl const Add42 for () {
|
||||
|
||||
fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
//~^ ERROR `~const` is not allowed here
|
||||
//~| ERROR cannot call
|
||||
Foo
|
||||
}
|
||||
|
||||
|
@ -10,5 +10,14 @@ note: this function is not `const`, so it cannot have `~const` trait bounds
|
||||
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
error[E0015]: cannot call non-const fn `<A as Add42>::add` in constants
|
||||
--> $DIR/tilde-const-and-const-params.rs:25:61
|
||||
|
|
||||
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
| ^^^^^^^^^
|
||||
|
|
||||
= note: calls in constants are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
||||
|
@ -1,4 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::foo` in constant functions
|
||||
--> $DIR/tilde_const_on_impl_bound.rs:14:16
|
||||
|
|
||||
LL | self.0.foo()
|
||||
| ^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -3,7 +3,7 @@
|
||||
// (`rustc_const_eval` instead of `rustc_hir_analysis`) Therefore one file as a
|
||||
// test is not enough.
|
||||
// known-bug: #110395
|
||||
// check-pass
|
||||
// FIXME check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
|
@ -0,0 +1,51 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
|
||||
--> $DIR/trait-where-clause-const.rs:20:5
|
||||
|
|
||||
LL | T::a();
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::b` in constant functions
|
||||
--> $DIR/trait-where-clause-const.rs:21:5
|
||||
|
|
||||
LL | T::b();
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::c::<T>` in constant functions
|
||||
--> $DIR/trait-where-clause-const.rs:23:5
|
||||
|
|
||||
LL | T::c::<T>();
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::a` in constant functions
|
||||
--> $DIR/trait-where-clause-const.rs:28:5
|
||||
|
|
||||
LL | T::a();
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::b` in constant functions
|
||||
--> $DIR/trait-where-clause-const.rs:29:5
|
||||
|
|
||||
LL | T::b();
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::c::<T>` in constant functions
|
||||
--> $DIR/trait-where-clause-const.rs:30:5
|
||||
|
|
||||
LL | T::c::<T>();
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,4 +1,5 @@
|
||||
// run-pass
|
||||
// known-bug: #110395
|
||||
// FIXME run-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<Self as Bar>::bar` in constant functions
|
||||
--> $DIR/trait-where-clause-run.rs:14:9
|
||||
|
|
||||
LL | <Self as Bar>::bar() * 6
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
@ -1,4 +1,5 @@
|
||||
// check-pass
|
||||
// known-bug: #110395
|
||||
// FIXME check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
error[E0015]: cannot call non-const fn `<T as Foo>::bar` in constant functions
|
||||
--> $DIR/trait-where-clause-self-referential.rs:22:5
|
||||
|
|
||||
LL | T::bar();
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0015`.
|
Loading…
Reference in New Issue
Block a user