Skip to content

Commit 0146969

Browse files
authored
Rollup merge of #105611 - BoxyUwU:more_granular_placeholderification, r=wesleywiser
fold instead of obliterating args Fixes #105608 we call `const_eval_resolve` on the following constant: ``` def: playground::{impl#0}::and::{constant#0}, substs: [ ConstKind::Unevaluated { def: playground::{impl#0}::and::{constant#0}, substs: [ ConstKind::Value(0x0), _, ] } _, ], ``` when expanded out to `ConstKind::Expr` there are no infer vars so we attempt to evaluate it after replacing infer vars with garbage, however the current logic for replacing with garbage replaces _the whole arg containing the infer var_ rather than just the infer var. This means that after garbage replacement has occured we attempt to evaluate: ``` def: playground::{impl#0}::and::{constant#0}, substs: [ PLACEHOLDER, PLACEHOLDER, ], ``` Which then leads to ctfe being unable to evaluate the const. With this PR we attempt to evaluate: ``` def: playground::{impl#0}::and::{constant#0}, substs: [ ConstKind::Unevaluated { def: playground::{impl#0}::and::{constant#0}, substs: [ ConstKind::Value(0x0), PLACEHOLDER, ] } PLACEHOLDER, ], ``` which ctfe _can_ handle. I am not entirely sure why this function is supposed to replace params with placeholders rather than just inference vars 🤔
2 parents 939880a + 5573485 commit 0146969

File tree

3 files changed

+67
-15
lines changed

3 files changed

+67
-15
lines changed

compiler/rustc_infer/src/infer/mod.rs

+38-15
Original file line numberDiff line numberDiff line change
@@ -2014,31 +2014,54 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
20142014
tcx: TyCtxt<'tcx>,
20152015
substs: SubstsRef<'tcx>,
20162016
) -> SubstsRef<'tcx> {
2017-
tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
2018-
match arg.unpack() {
2019-
GenericArgKind::Type(_) if arg.has_non_region_param() || arg.has_non_region_infer() => {
2020-
tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
2017+
struct ReplaceParamAndInferWithPlaceholder<'tcx> {
2018+
tcx: TyCtxt<'tcx>,
2019+
idx: usize,
2020+
}
2021+
2022+
impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> {
2023+
fn tcx(&self) -> TyCtxt<'tcx> {
2024+
self.tcx
2025+
}
2026+
2027+
fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
2028+
if let ty::Infer(_) = t.kind() {
2029+
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
20212030
universe: ty::UniverseIndex::ROOT,
2022-
name: ty::BoundVar::from_usize(idx),
2031+
name: ty::BoundVar::from_usize({
2032+
let idx = self.idx;
2033+
self.idx += 1;
2034+
idx
2035+
}),
20232036
}))
2024-
.into()
2037+
} else {
2038+
t.super_fold_with(self)
20252039
}
2026-
GenericArgKind::Const(ct) if ct.has_non_region_infer() || ct.has_non_region_param() => {
2027-
let ty = ct.ty();
2028-
// If the type references param or infer, replace that too...
2040+
}
2041+
2042+
fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
2043+
if let ty::ConstKind::Infer(_) = c.kind() {
2044+
let ty = c.ty();
2045+
// If the type references param or infer then ICE ICE ICE
20292046
if ty.has_non_region_param() || ty.has_non_region_infer() {
2030-
bug!("const `{ct}`'s type should not reference params or types");
2047+
bug!("const `{c}`'s type should not reference params or types");
20312048
}
2032-
tcx.mk_const(
2049+
self.tcx.mk_const(
20332050
ty::PlaceholderConst {
20342051
universe: ty::UniverseIndex::ROOT,
2035-
name: ty::BoundVar::from_usize(idx),
2052+
name: ty::BoundVar::from_usize({
2053+
let idx = self.idx;
2054+
self.idx += 1;
2055+
idx
2056+
}),
20362057
},
20372058
ty,
20382059
)
2039-
.into()
2060+
} else {
2061+
c.super_fold_with(self)
20402062
}
2041-
_ => arg,
20422063
}
2043-
}))
2064+
}
2065+
2066+
substs.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
20442067
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#![feature(generic_const_exprs)]
2+
#![allow(incomplete_features)]
3+
4+
struct Combination<const STRATEGIES: usize>;
5+
6+
impl<const STRATEGIES: usize> Combination<STRATEGIES> {
7+
fn and<M>(self) -> Combination<{ STRATEGIES + 1 }> {
8+
Combination
9+
}
10+
}
11+
12+
pub fn main() {
13+
Combination::<0>.and::<_>().and::<_>();
14+
//~^ ERROR: type annotations needed
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/issue-105608.rs:13:22
3+
|
4+
LL | Combination::<0>.and::<_>().and::<_>();
5+
| ^^^ cannot infer type of the type parameter `M` declared on the associated function `and`
6+
|
7+
help: consider specifying the generic argument
8+
|
9+
LL | Combination::<0>.and::<_>().and::<_>();
10+
| ~~~~~
11+
12+
error: aborting due to previous error
13+
14+
For more information about this error, try `rustc --explain E0282`.

0 commit comments

Comments
 (0)