Skip to content

Commit cd8cc91

Browse files
committed
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.
2 parents 4136b59 + ee96ae0 commit cd8cc91

File tree

5 files changed

+33
-15
lines changed

5 files changed

+33
-15
lines changed

compiler/rustc_middle/src/traits/select.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ pub enum SelectionCandidate<'tcx> {
119119

120120
/// This is a trait matching with a projected type as `Self`, and we found
121121
/// an applicable bound in the trait definition. The `usize` is an index
122-
/// into the list returned by `tcx.item_bounds`.
123-
ProjectionCandidate(usize),
122+
/// into the list returned by `tcx.item_bounds`. The constness is the
123+
/// constness of the bound in the trait.
124+
ProjectionCandidate(usize, ty::BoundConstness),
124125

125126
/// Implementation of a `Fn`-family trait by one of the anonymous types
126127
/// generated for an `||` expression.

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
362362
.infcx
363363
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
364364

365-
candidates.vec.extend(result.into_iter().map(ProjectionCandidate));
365+
candidates
366+
.vec
367+
.extend(result.into_iter().map(|(idx, constness)| ProjectionCandidate(idx, constness)));
366368
}
367369

368370
/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
6868
ImplSource::AutoImpl(data)
6969
}
7070

71-
ProjectionCandidate(idx) => {
71+
ProjectionCandidate(idx, constness) => {
7272
let obligations = self.confirm_projection_candidate(obligation, idx)?;
73-
// FIXME(jschievink): constness
74-
ImplSource::Param(obligations, ty::BoundConstness::NotConst)
73+
ImplSource::Param(obligations, constness)
7574
}
7675

7776
ObjectCandidate(idx) => {

compiler/rustc_trait_selection/src/traits/select/mod.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11921192
ImplCandidate(def_id) if tcx.constness(def_id) == hir::Constness::Const => {}
11931193
// const param
11941194
ParamCandidate(trait_pred) if trait_pred.is_const_if_const() => {}
1195+
// const projection
1196+
ProjectionCandidate(_, ty::BoundConstness::ConstIfConst) => {}
11951197
// auto trait impl
11961198
AutoImplCandidate(..) => {}
11971199
// generator, this will raise error in other places
@@ -1399,7 +1401,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13991401
fn match_projection_obligation_against_definition_bounds(
14001402
&mut self,
14011403
obligation: &TraitObligation<'tcx>,
1402-
) -> smallvec::SmallVec<[usize; 2]> {
1404+
) -> smallvec::SmallVec<[(usize, ty::BoundConstness); 2]> {
14031405
let poly_trait_predicate = self.infcx().resolve_vars_if_possible(obligation.predicate);
14041406
let placeholder_trait_predicate =
14051407
self.infcx().replace_bound_vars_with_placeholders(poly_trait_predicate);
@@ -1447,7 +1449,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
14471449
_ => false,
14481450
}
14491451
}) {
1450-
return Some(idx);
1452+
return Some((idx, pred.constness));
14511453
}
14521454
}
14531455
None
@@ -1683,9 +1685,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
16831685
| BuiltinCandidate { .. }
16841686
| TraitAliasCandidate(..)
16851687
| ObjectCandidate(_)
1686-
| ProjectionCandidate(_),
1688+
| ProjectionCandidate(..),
16871689
) => !is_global(cand),
1688-
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => {
1690+
(ObjectCandidate(_) | ProjectionCandidate(..), ParamCandidate(ref cand)) => {
16891691
// Prefer these to a global where-clause bound
16901692
// (see issue #50825).
16911693
is_global(cand)
@@ -1707,20 +1709,20 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17071709
is_global(cand) && other.evaluation.must_apply_modulo_regions()
17081710
}
17091711

1710-
(ProjectionCandidate(i), ProjectionCandidate(j))
1712+
(ProjectionCandidate(i, _), ProjectionCandidate(j, _))
17111713
| (ObjectCandidate(i), ObjectCandidate(j)) => {
17121714
// Arbitrarily pick the lower numbered candidate for backwards
17131715
// compatibility reasons. Don't let this affect inference.
17141716
i < j && !needs_infer
17151717
}
1716-
(ObjectCandidate(_), ProjectionCandidate(_))
1717-
| (ProjectionCandidate(_), ObjectCandidate(_)) => {
1718+
(ObjectCandidate(_), ProjectionCandidate(..))
1719+
| (ProjectionCandidate(..), ObjectCandidate(_)) => {
17181720
bug!("Have both object and projection candidate")
17191721
}
17201722

17211723
// Arbitrarily give projection and object candidates priority.
17221724
(
1723-
ObjectCandidate(_) | ProjectionCandidate(_),
1725+
ObjectCandidate(_) | ProjectionCandidate(..),
17241726
ImplCandidate(..)
17251727
| ClosureCandidate
17261728
| GeneratorCandidate
@@ -1742,7 +1744,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
17421744
| TraitUpcastingUnsizeCandidate(_)
17431745
| BuiltinCandidate { .. }
17441746
| TraitAliasCandidate(..),
1745-
ObjectCandidate(_) | ProjectionCandidate(_),
1747+
ObjectCandidate(_) | ProjectionCandidate(..),
17461748
) => false,
17471749

17481750
(&ImplCandidate(other_def), &ImplCandidate(victim_def)) => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// check-pass
2+
#![feature(const_trait_impl)]
3+
4+
#[const_trait]
5+
trait Foo {
6+
type Assoc: ~const Foo;
7+
fn foo() {}
8+
}
9+
10+
const fn foo<T: ~const Foo>() {
11+
<T as Foo>::Assoc::foo();
12+
}
13+
14+
fn main() {}

0 commit comments

Comments
 (0)