Skip to content

Commit

Permalink
Rollup merge of #105611 - BoxyUwU:more_granular_placeholderification,…
Browse files Browse the repository at this point in the history
… 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 🤔
  • Loading branch information
matthiaskrgr authored Dec 14, 2022
2 parents 939880a + 5573485 commit 0146969
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 15 deletions.
53 changes: 38 additions & 15 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2014,31 +2014,54 @@ fn replace_param_and_infer_substs_with_placeholder<'tcx>(
tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>,
) -> SubstsRef<'tcx> {
tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
match arg.unpack() {
GenericArgKind::Type(_) if arg.has_non_region_param() || arg.has_non_region_infer() => {
tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
struct ReplaceParamAndInferWithPlaceholder<'tcx> {
tcx: TyCtxt<'tcx>,
idx: usize,
}

impl<'tcx> TypeFolder<'tcx> for ReplaceParamAndInferWithPlaceholder<'tcx> {
fn tcx(&self) -> TyCtxt<'tcx> {
self.tcx
}

fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
if let ty::Infer(_) = t.kind() {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: ty::UniverseIndex::ROOT,
name: ty::BoundVar::from_usize(idx),
name: ty::BoundVar::from_usize({
let idx = self.idx;
self.idx += 1;
idx
}),
}))
.into()
} else {
t.super_fold_with(self)
}
GenericArgKind::Const(ct) if ct.has_non_region_infer() || ct.has_non_region_param() => {
let ty = ct.ty();
// If the type references param or infer, replace that too...
}

fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> {
if let ty::ConstKind::Infer(_) = c.kind() {
let ty = c.ty();
// If the type references param or infer then ICE ICE ICE
if ty.has_non_region_param() || ty.has_non_region_infer() {
bug!("const `{ct}`'s type should not reference params or types");
bug!("const `{c}`'s type should not reference params or types");
}
tcx.mk_const(
self.tcx.mk_const(
ty::PlaceholderConst {
universe: ty::UniverseIndex::ROOT,
name: ty::BoundVar::from_usize(idx),
name: ty::BoundVar::from_usize({
let idx = self.idx;
self.idx += 1;
idx
}),
},
ty,
)
.into()
} else {
c.super_fold_with(self)
}
_ => arg,
}
}))
}

substs.fold_with(&mut ReplaceParamAndInferWithPlaceholder { tcx, idx: 0 })
}
15 changes: 15 additions & 0 deletions src/test/ui/const-generics/generic_const_exprs/issue-105608.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#![feature(generic_const_exprs)]
#![allow(incomplete_features)]

struct Combination<const STRATEGIES: usize>;

impl<const STRATEGIES: usize> Combination<STRATEGIES> {
fn and<M>(self) -> Combination<{ STRATEGIES + 1 }> {
Combination
}
}

pub fn main() {
Combination::<0>.and::<_>().and::<_>();
//~^ ERROR: type annotations needed
}
14 changes: 14 additions & 0 deletions src/test/ui/const-generics/generic_const_exprs/issue-105608.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0282]: type annotations needed
--> $DIR/issue-105608.rs:13:22
|
LL | Combination::<0>.and::<_>().and::<_>();
| ^^^ cannot infer type of the type parameter `M` declared on the associated function `and`
|
help: consider specifying the generic argument
|
LL | Combination::<0>.and::<_>().and::<_>();
| ~~~~~

error: aborting due to previous error

For more information about this error, try `rustc --explain E0282`.

0 comments on commit 0146969

Please sign in to comment.