Rollup merge of #99704 - fee1-dead-contrib:add_self_tilde_const_trait, r=oli-obk
Add `Self: ~const Trait` to traits with `#[const_trait]` r? `@oli-obk`
This commit is contained in:
commit
28b44ff5d4
30 changed files with 199 additions and 209 deletions
|
@ -23,8 +23,8 @@ use rustc_trait_selection::traits::SelectionContext;
|
|||
|
||||
use super::ConstCx;
|
||||
use crate::errors::{
|
||||
MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrComparisonErr, RawPtrToIntErr,
|
||||
StaticAccessErr, TransientMutBorrowErr, TransientMutBorrowErrRaw,
|
||||
MutDerefErr, NonConstOpErr, PanicNonStrErr, RawPtrToIntErr, StaticAccessErr,
|
||||
TransientMutBorrowErr, TransientMutBorrowErrRaw,
|
||||
};
|
||||
use crate::util::{call_kind, CallDesugaringKind, CallKind};
|
||||
|
||||
|
@ -654,10 +654,10 @@ pub struct RawPtrComparison;
|
|||
impl<'tcx> NonConstOp<'tcx> for RawPtrComparison {
|
||||
fn build_error(
|
||||
&self,
|
||||
ccx: &ConstCx<'_, 'tcx>,
|
||||
_: &ConstCx<'_, 'tcx>,
|
||||
span: Span,
|
||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||
ccx.tcx.sess.create_err(RawPtrComparisonErr { span })
|
||||
span_bug!(span, "raw ptr comparison should already be caught in the trait system");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -829,6 +829,14 @@ impl<'tcx> TraitPredicate<'tcx> {
|
|||
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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> PolyTraitPredicate<'tcx> {
|
||||
|
|
|
@ -2556,7 +2556,7 @@ define_print_and_forward_display! {
|
|||
|
||||
ty::TraitPredicate<'tcx> {
|
||||
p!(print(self.trait_ref.self_ty()), ": ");
|
||||
if let ty::BoundConstness::ConstIfConst = self.constness {
|
||||
if let ty::BoundConstness::ConstIfConst = self.constness && cx.tcx().features().const_trait_impl {
|
||||
p!("~const ");
|
||||
}
|
||||
p!(print(self.trait_ref.print_only_trait_path()))
|
||||
|
|
|
@ -666,7 +666,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
);
|
||||
} else if !suggested {
|
||||
// Can't show anything else useful, try to find similar impls.
|
||||
let impl_candidates = self.find_similar_impl_candidates(trait_ref);
|
||||
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
|
||||
if !self.report_similar_impl_candidates(
|
||||
impl_candidates,
|
||||
trait_ref,
|
||||
|
@ -701,7 +701,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
{
|
||||
let trait_ref = trait_pred.to_poly_trait_ref();
|
||||
let impl_candidates =
|
||||
self.find_similar_impl_candidates(trait_ref);
|
||||
self.find_similar_impl_candidates(trait_pred);
|
||||
self.report_similar_impl_candidates(
|
||||
impl_candidates,
|
||||
trait_ref,
|
||||
|
@ -1325,7 +1325,7 @@ trait InferCtxtPrivExt<'hir, 'tcx> {
|
|||
|
||||
fn find_similar_impl_candidates(
|
||||
&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> Vec<ImplCandidate<'tcx>>;
|
||||
|
||||
fn report_similar_impl_candidates(
|
||||
|
@ -1694,18 +1694,22 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
|
|||
|
||||
fn find_similar_impl_candidates(
|
||||
&self,
|
||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) -> Vec<ImplCandidate<'tcx>> {
|
||||
self.tcx
|
||||
.all_impls(trait_ref.def_id())
|
||||
.all_impls(trait_pred.def_id())
|
||||
.filter_map(|def_id| {
|
||||
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative {
|
||||
if self.tcx.impl_polarity(def_id) == ty::ImplPolarity::Negative
|
||||
|| !trait_pred
|
||||
.skip_binder()
|
||||
.is_constness_satisfied_by(self.tcx.constness(def_id))
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let imp = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||
|
||||
self.fuzzy_match_tys(trait_ref.skip_binder().self_ty(), imp.self_ty(), false)
|
||||
self.fuzzy_match_tys(trait_pred.skip_binder().self_ty(), imp.self_ty(), false)
|
||||
.map(|similarity| ImplCandidate { trait_ref: imp, similarity })
|
||||
})
|
||||
.collect()
|
||||
|
|
|
@ -2090,10 +2090,17 @@ fn predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicates<'_> {
|
|||
// 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).without_const().to_predicate(tcx),
|
||||
ty::TraitRef::identity(tcx, def_id).with_constness(constness).to_predicate(tcx),
|
||||
span,
|
||||
))));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue