Auto merge of #101989 - fee1-dead-contrib:const_trait_impl-assoc-caller-bounds, r=oli-obk
make projection bounds with const bounds satisfy const Fixes #101982.
This commit is contained in:
commit
cd8cc91045
5 changed files with 33 additions and 15 deletions
|
@ -119,8 +119,9 @@ pub enum SelectionCandidate<'tcx> {
|
||||||
|
|
||||||
/// This is a trait matching with a projected type as `Self`, and we found
|
/// This is a trait matching with a projected type as `Self`, and we found
|
||||||
/// an applicable bound in the trait definition. The `usize` is an index
|
/// an applicable bound in the trait definition. The `usize` is an index
|
||||||
/// into the list returned by `tcx.item_bounds`.
|
/// into the list returned by `tcx.item_bounds`. The constness is the
|
||||||
ProjectionCandidate(usize),
|
/// constness of the bound in the trait.
|
||||||
|
ProjectionCandidate(usize, ty::BoundConstness),
|
||||||
|
|
||||||
/// Implementation of a `Fn`-family trait by one of the anonymous types
|
/// Implementation of a `Fn`-family trait by one of the anonymous types
|
||||||
/// generated for an `||` expression.
|
/// generated for an `||` expression.
|
||||||
|
|
|
@ -362,7 +362,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
.infcx
|
.infcx
|
||||||
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
|
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
|
||||||
|
|
||||||
candidates.vec.extend(result.into_iter().map(ProjectionCandidate));
|
candidates
|
||||||
|
.vec
|
||||||
|
.extend(result.into_iter().map(|(idx, constness)| ProjectionCandidate(idx, constness)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
|
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
|
||||||
|
|
|
@ -68,10 +68,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
ImplSource::AutoImpl(data)
|
ImplSource::AutoImpl(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
ProjectionCandidate(idx) => {
|
ProjectionCandidate(idx, constness) => {
|
||||||
let obligations = self.confirm_projection_candidate(obligation, idx)?;
|
let obligations = self.confirm_projection_candidate(obligation, idx)?;
|
||||||
// FIXME(jschievink): constness
|
ImplSource::Param(obligations, constness)
|
||||||
ImplSource::Param(obligations, ty::BoundConstness::NotConst)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectCandidate(idx) => {
|
ObjectCandidate(idx) => {
|
||||||
|
|
|
@ -1192,6 +1192,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
|
ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
|
||||||
// const param
|
// const param
|
||||||
ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
|
ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
|
||||||
|
// const projection
|
||||||
|
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) => {}
|
||||||
// auto trait impl
|
// auto trait impl
|
||||||
AutoImplCandidate(..) => {}
|
AutoImplCandidate(..) => {}
|
||||||
// generator, this will raise error in other places
|
// generator, this will raise error in other places
|
||||||
|
@ -1399,7 +1401,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
fn match_projection_obligation_against_definition_bounds(
|
fn match_projection_obligation_against_definition_bounds(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
) -> smallvec::SmallVec<[usize; 2]> {
|
) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> {
|
||||||
let poly_trait_predicate = self.infcx().resolve_vars_if_possible(obligation.predicate);
|
let poly_trait_predicate = self.infcx().resolve_vars_if_possible(obligation.predicate);
|
||||||
let placeholder_trait_predicate =
|
let placeholder_trait_predicate =
|
||||||
self.infcx().replace_bound_vars_with_placeholders(poly_trait_predicate);
|
self.infcx().replace_bound_vars_with_placeholders(poly_trait_predicate);
|
||||||
|
@ -1447,7 +1449,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
return Some(idx);
|
return Some((idx, pred.constness));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
|
@ -1683,9 +1685,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
| BuiltinCandidate { .. }
|
| BuiltinCandidate { .. }
|
||||||
| TraitAliasCandidate(..)
|
| TraitAliasCandidate(..)
|
||||||
| ObjectCandidate(_)
|
| ObjectCandidate(_)
|
||||||
| ProjectionCandidate(_),
|
| ProjectionCandidate(..),
|
||||||
) => !is_global(cand),
|
) => !is_global(cand),
|
||||||
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => {
|
(ObjectCandidate(_) | ProjectionCandidate(..), ParamCandidate(ref cand)) => {
|
||||||
// Prefer these to a global where-clause bound
|
// Prefer these to a global where-clause bound
|
||||||
// (see issue #50825).
|
// (see issue #50825).
|
||||||
is_global(cand)
|
is_global(cand)
|
||||||
|
@ -1707,20 +1709,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
is_global(cand) && other.evaluation.must_apply_modulo_regions()
|
is_global(cand) && other.evaluation.must_apply_modulo_regions()
|
||||||
}
|
}
|
||||||
|
|
||||||
(ProjectionCandidate(i), ProjectionCandidate(j))
|
(ProjectionCandidate(i, _), ProjectionCandidate(j, _))
|
||||||
| (ObjectCandidate(i), ObjectCandidate(j)) => {
|
| (ObjectCandidate(i), ObjectCandidate(j)) => {
|
||||||
// Arbitrarily pick the lower numbered candidate for backwards
|
// Arbitrarily pick the lower numbered candidate for backwards
|
||||||
// compatibility reasons. Don't let this affect inference.
|
// compatibility reasons. Don't let this affect inference.
|
||||||
i < j && !needs_infer
|
i < j && !needs_infer
|
||||||
}
|
}
|
||||||
(ObjectCandidate(_), ProjectionCandidate(_))
|
(ObjectCandidate(_), ProjectionCandidate(..))
|
||||||
| (ProjectionCandidate(_), ObjectCandidate(_)) => {
|
| (ProjectionCandidate(..), ObjectCandidate(_)) => {
|
||||||
bug!("Have both object and projection candidate")
|
bug!("Have both object and projection candidate")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arbitrarily give projection and object candidates priority.
|
// Arbitrarily give projection and object candidates priority.
|
||||||
(
|
(
|
||||||
ObjectCandidate(_) | ProjectionCandidate(_),
|
ObjectCandidate(_) | ProjectionCandidate(..),
|
||||||
ImplCandidate(..)
|
ImplCandidate(..)
|
||||||
| ClosureCandidate
|
| ClosureCandidate
|
||||||
| GeneratorCandidate
|
| GeneratorCandidate
|
||||||
|
@ -1742,7 +1744,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
| TraitUpcastingUnsizeCandidate(_)
|
| TraitUpcastingUnsizeCandidate(_)
|
||||||
| BuiltinCandidate { .. }
|
| BuiltinCandidate { .. }
|
||||||
| TraitAliasCandidate(..),
|
| TraitAliasCandidate(..),
|
||||||
ObjectCandidate(_) | ProjectionCandidate(_),
|
ObjectCandidate(_) | ProjectionCandidate(..),
|
||||||
) => false,
|
) => false,
|
||||||
|
|
||||||
(&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
|
(&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
// check-pass
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Foo {
|
||||||
|
type Assoc: ~const Foo;
|
||||||
|
fn foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn foo<T: ~const Foo>() {
|
||||||
|
<T as Foo>::Assoc::foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Add table
Add a link
Reference in a new issue