Skip to content

Commit f1618e8

Browse files
handle consts with param/infer in const_eval_resolve better
1 parent 6dbae3a commit f1618e8

File tree

4 files changed

+47
-62
lines changed

4 files changed

+47
-62
lines changed

compiler/rustc_infer/src/infer/mod.rs

+41-6
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
2121
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
2222
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
2323
use rustc_middle::traits::select;
24-
use rustc_middle::ty::abstract_const::AbstractConst;
24+
use rustc_middle::ty::abstract_const::{AbstractConst, FailureKind};
2525
use rustc_middle::ty::error::{ExpectedFound, TypeError};
2626
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
2727
use rustc_middle::ty::relate::RelateResult;
@@ -1683,7 +1683,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16831683
#[instrument(skip(self), level = "debug")]
16841684
pub fn const_eval_resolve(
16851685
&self,
1686-
param_env: ty::ParamEnv<'tcx>,
1686+
mut param_env: ty::ParamEnv<'tcx>,
16871687
unevaluated: ty::Unevaluated<'tcx>,
16881688
span: Option<Span>,
16891689
) -> EvalToValTreeResult<'tcx> {
@@ -1694,10 +1694,45 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16941694
// variables
16951695
if substs.has_infer_types_or_consts() {
16961696
let ac = AbstractConst::new(self.tcx, unevaluated.shrink());
1697-
if let Ok(None) = ac {
1698-
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
1699-
} else {
1700-
return Err(ErrorHandled::TooGeneric);
1697+
match ac {
1698+
Ok(None) => {
1699+
substs = InternalSubsts::identity_for_item(self.tcx, unevaluated.def.did);
1700+
param_env = self.tcx.param_env(unevaluated.def.did);
1701+
}
1702+
Ok(Some(ct)) => {
1703+
if ct.unify_failure_kind(self.tcx) == FailureKind::Concrete {
1704+
substs = self.tcx.mk_substs(substs.iter().enumerate().map(|(idx, arg)| {
1705+
let needs_replacement =
1706+
arg.has_param_types_or_consts() || arg.has_infer_types_or_consts();
1707+
match arg.unpack() {
1708+
GenericArgKind::Type(_) if needs_replacement => self
1709+
.tcx
1710+
.mk_ty(ty::Placeholder(ty::PlaceholderType {
1711+
universe: ty::UniverseIndex::ROOT,
1712+
name: ty::BoundVar::from_usize(idx),
1713+
}))
1714+
.into(),
1715+
GenericArgKind::Const(ct) if needs_replacement => self
1716+
.tcx
1717+
.mk_const(ty::ConstS {
1718+
ty: ct.ty(),
1719+
kind: ty::ConstKind::Placeholder(ty::PlaceholderConst {
1720+
universe: ty::UniverseIndex::ROOT,
1721+
name: ty::BoundConst {
1722+
var: ty::BoundVar::from_usize(idx),
1723+
ty: ct.ty(),
1724+
},
1725+
}),
1726+
})
1727+
.into(),
1728+
_ => arg,
1729+
}
1730+
}));
1731+
} else {
1732+
return Err(ErrorHandled::TooGeneric);
1733+
}
1734+
}
1735+
Err(guar) => return Err(ErrorHandled::Reported(guar)),
17011736
}
17021737
}
17031738

compiler/rustc_trait_selection/src/traits/const_evaluatable.rs

+4-13
Original file line numberDiff line numberDiff line change
@@ -185,21 +185,12 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
185185
}
186186
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
187187
match concrete {
188-
Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() {
189-
NotConstEvaluatable::MentionsInfer
190-
} else if uv.has_param_types_or_consts() {
191-
infcx
192-
.tcx
193-
.sess
194-
.delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv));
195-
NotConstEvaluatable::MentionsParam
196-
} else {
197-
let guar = infcx.tcx.sess.delay_span_bug(
188+
Err(ErrorHandled::TooGeneric) => {
189+
Err(NotConstEvaluatable::Error(infcx.tcx.sess.delay_span_bug(
198190
span,
199191
format!("Missing value for constant, but no error reported?"),
200-
);
201-
NotConstEvaluatable::Error(guar)
202-
}),
192+
)))
193+
}
203194
Err(ErrorHandled::Linted) => {
204195
let reported = infcx
205196
.tcx

src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
// check-pass
2+
13
#![feature(generic_const_exprs)]
24
#![allow(incomplete_features)]
35

@@ -21,11 +23,6 @@ where
2123
}
2224

2325
fn main() {
24-
// FIXME(generic_const_exprs): We can't correctly infer `T` which requires
25-
// evaluating `{ N + 1 }` which has substs containing an inference var
2626
let mut _q = Default::default();
27-
//~^ ERROR type annotations needed
28-
2927
_q = foo::<_, 2>(_q);
30-
//~^ ERROR type annotations needed
3128
}

src/test/ui/const-generics/generic_const_exprs/const_eval_resolve_canonical.stderr

-38
This file was deleted.

0 commit comments

Comments
 (0)