Auto merge of #87375 - fee1-dead:move-constness-to-traitpred, r=oli-obk

Try filtering out non-const impls when we expect const impls

**TL;DR**: Associated types on const impls are now bounded; we now disallow calling a const function with bounds when the specified type param only has a non-const impl.

r? `@oli-obk`
This commit is contained in:
bors
2021-08-14 12:06:34 +00:00
68 changed files with 517 additions and 211 deletions

View File

@@ -461,7 +461,7 @@ pub enum PredicateKind<'tcx> {
/// A trait predicate will have `Constness::Const` if it originates
/// from a bound on a `const fn` without the `?const` opt-out (e.g.,
/// `const fn foobar<Foo: Bar>() {}`).
Trait(TraitPredicate<'tcx>, Constness),
Trait(TraitPredicate<'tcx>),
/// `where 'a: 'b`
RegionOutlives(RegionOutlivesPredicate<'tcx>),
@@ -617,6 +617,11 @@ impl<'tcx> Predicate<'tcx> {
#[derive(HashStable, TypeFoldable)]
pub struct TraitPredicate<'tcx> {
pub trait_ref: TraitRef<'tcx>,
/// A trait predicate will have `Constness::Const` if it originates
/// from a bound on a `const fn` without the `?const` opt-out (e.g.,
/// `const fn foobar<Foo: Bar>() {}`).
pub constness: hir::Constness,
}
pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
@@ -750,8 +755,11 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> {
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<TraitRef<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateKind::Trait(ty::TraitPredicate { trait_ref: self.value }, self.constness)
.to_predicate(tcx)
PredicateKind::Trait(ty::TraitPredicate {
trait_ref: self.value,
constness: self.constness,
})
.to_predicate(tcx)
}
}
@@ -759,15 +767,15 @@ impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitRef<'tcx>> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.value
.map_bound(|trait_ref| {
PredicateKind::Trait(ty::TraitPredicate { trait_ref }, self.constness)
PredicateKind::Trait(ty::TraitPredicate { trait_ref, constness: self.constness })
})
.to_predicate(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for ConstnessAnd<PolyTraitPredicate<'tcx>> {
impl<'tcx> ToPredicate<'tcx> for PolyTraitPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.value.map_bound(|value| PredicateKind::Trait(value, self.constness)).to_predicate(tcx)
self.map_bound(PredicateKind::Trait).to_predicate(tcx)
}
}
@@ -793,8 +801,8 @@ impl<'tcx> Predicate<'tcx> {
pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
let predicate = self.kind();
match predicate.skip_binder() {
PredicateKind::Trait(t, constness) => {
Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) })
PredicateKind::Trait(t) => {
Some(ConstnessAnd { constness: t.constness, value: predicate.rebind(t.trait_ref) })
}
PredicateKind::Projection(..)
| PredicateKind::Subtype(..)