fix gce typing_mode mismatch
This commit is contained in:
parent
7db7489f9b
commit
58936c1d2a
3 changed files with 89 additions and 18 deletions
|
@ -551,8 +551,18 @@ pub fn try_evaluate_const<'tcx>(
|
||||||
| ty::ConstKind::Placeholder(_)
|
| ty::ConstKind::Placeholder(_)
|
||||||
| ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers),
|
| ty::ConstKind::Expr(_) => Err(EvaluateConstErr::HasGenericsOrInfers),
|
||||||
ty::ConstKind::Unevaluated(uv) => {
|
ty::ConstKind::Unevaluated(uv) => {
|
||||||
// Postpone evaluation of constants that depend on generic parameters or inference variables.
|
// Postpone evaluation of constants that depend on generic parameters or
|
||||||
let (args, param_env) = if tcx.features().generic_const_exprs()
|
// inference variables.
|
||||||
|
//
|
||||||
|
// We use `TypingMode::PostAnalysis` here which is not *technically* correct
|
||||||
|
// to be revealing opaque types here as borrowcheck has not run yet. However,
|
||||||
|
// CTFE itself uses `TypingMode::PostAnalysis` unconditionally even during
|
||||||
|
// typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
|
||||||
|
// As a result we always use a revealed env when resolving the instance to evaluate.
|
||||||
|
//
|
||||||
|
// FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
|
||||||
|
// instead of having this logic here
|
||||||
|
let (args, typing_env) = if tcx.features().generic_const_exprs()
|
||||||
&& uv.has_non_region_infer()
|
&& uv.has_non_region_infer()
|
||||||
{
|
{
|
||||||
// `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
|
// `feature(generic_const_exprs)` causes anon consts to inherit all parent generics. This can cause
|
||||||
|
@ -568,13 +578,17 @@ pub fn try_evaluate_const<'tcx>(
|
||||||
// the generic arguments provided for it, then we should *not* attempt to evaluate it.
|
// the generic arguments provided for it, then we should *not* attempt to evaluate it.
|
||||||
return Err(EvaluateConstErr::HasGenericsOrInfers);
|
return Err(EvaluateConstErr::HasGenericsOrInfers);
|
||||||
} else {
|
} else {
|
||||||
(replace_param_and_infer_args_with_placeholder(tcx, uv.args), param_env)
|
let args = replace_param_and_infer_args_with_placeholder(tcx, uv.args);
|
||||||
|
let typing_env = infcx
|
||||||
|
.typing_env(tcx.erase_regions(param_env))
|
||||||
|
.with_post_analysis_normalized(tcx);
|
||||||
|
(args, typing_env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) | Ok(None) => {
|
Err(_) | Ok(None) => {
|
||||||
let args = GenericArgs::identity_for_item(tcx, uv.def);
|
let args = GenericArgs::identity_for_item(tcx, uv.def);
|
||||||
let param_env = tcx.param_env(uv.def);
|
let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
|
||||||
(args, param_env)
|
(args, typing_env)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
|
} else if tcx.def_kind(uv.def) == DefKind::AnonConst && uv.has_non_region_infer() {
|
||||||
|
@ -593,27 +607,20 @@ pub fn try_evaluate_const<'tcx>(
|
||||||
);
|
);
|
||||||
|
|
||||||
let args = GenericArgs::identity_for_item(tcx, uv.def);
|
let args = GenericArgs::identity_for_item(tcx, uv.def);
|
||||||
let param_env = tcx.param_env(uv.def);
|
let typing_env = ty::TypingEnv::post_analysis(tcx, uv.def);
|
||||||
(args, param_env)
|
(args, typing_env)
|
||||||
} else {
|
} else {
|
||||||
// FIXME: This codepath is reachable under `associated_const_equality` and in the
|
// FIXME: This codepath is reachable under `associated_const_equality` and in the
|
||||||
// future will be reachable by `min_generic_const_args`. We should handle inference
|
// future will be reachable by `min_generic_const_args`. We should handle inference
|
||||||
// variables and generic parameters properly instead of doing nothing.
|
// variables and generic parameters properly instead of doing nothing.
|
||||||
(uv.args, param_env)
|
let typing_env = infcx
|
||||||
|
.typing_env(tcx.erase_regions(param_env))
|
||||||
|
.with_post_analysis_normalized(tcx);
|
||||||
|
(uv.args, typing_env)
|
||||||
};
|
};
|
||||||
let uv = ty::UnevaluatedConst::new(uv.def, args);
|
let uv = ty::UnevaluatedConst::new(uv.def, args);
|
||||||
|
|
||||||
// It's not *technically* correct to be revealing opaque types here as borrowcheck has
|
|
||||||
// not run yet. However, CTFE itself uses `TypingMode::PostAnalysis` unconditionally even
|
|
||||||
// during typeck and not doing so has a lot of (undesirable) fallout (#101478, #119821).
|
|
||||||
// As a result we always use a revealed env when resolving the instance to evaluate.
|
|
||||||
//
|
|
||||||
// FIXME: `const_eval_resolve_for_typeck` should probably just modify the env itself
|
|
||||||
// instead of having this logic here
|
|
||||||
let typing_env =
|
|
||||||
tcx.erase_regions(infcx.typing_env(param_env)).with_post_analysis_normalized(tcx);
|
|
||||||
let erased_uv = tcx.erase_regions(uv);
|
let erased_uv = tcx.erase_regions(uv);
|
||||||
|
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) {
|
match tcx.const_eval_resolve_for_typeck(typing_env, erased_uv, DUMMY_SP) {
|
||||||
Ok(Ok(val)) => Ok(ty::Const::new_value(
|
Ok(Ok(val)) => Ok(ty::Const::new_value(
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
// Regression test for #133271.
|
||||||
|
#![feature(generic_const_exprs)]
|
||||||
|
//~^ WARN the feature `generic_const_exprs` is incomplete
|
||||||
|
|
||||||
|
struct Foo;
|
||||||
|
impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
|
||||||
|
//~^ ERROR the const parameter `NUM` is not constrained by the impl trait, self type, or predicates
|
||||||
|
where
|
||||||
|
[(); 1 + 0]: Sized,
|
||||||
|
{
|
||||||
|
fn unimplemented(self, _: &Foo) -> Self::Output {
|
||||||
|
//~^ ERROR method `unimplemented` is not a member of trait `std::ops::Add`
|
||||||
|
//~| ERROR type annotations needed
|
||||||
|
loop {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,46 @@
|
||||||
|
error[E0407]: method `unimplemented` is not a member of trait `std::ops::Add`
|
||||||
|
--> $DIR/post-analysis-user-facing-param-env.rs:11:5
|
||||||
|
|
|
||||||
|
LL | / fn unimplemented(self, _: &Foo) -> Self::Output {
|
||||||
|
LL | |
|
||||||
|
LL | |
|
||||||
|
LL | | loop {}
|
||||||
|
LL | | }
|
||||||
|
| |_____^ not a member of trait `std::ops::Add`
|
||||||
|
|
||||||
|
warning: the feature `generic_const_exprs` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||||
|
--> $DIR/post-analysis-user-facing-param-env.rs:2:12
|
||||||
|
|
|
||||||
|
LL | #![feature(generic_const_exprs)]
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information
|
||||||
|
= note: `#[warn(incomplete_features)]` on by default
|
||||||
|
|
||||||
|
error[E0207]: the const parameter `NUM` is not constrained by the impl trait, self type, or predicates
|
||||||
|
--> $DIR/post-analysis-user-facing-param-env.rs:6:10
|
||||||
|
|
|
||||||
|
LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
|
||||||
|
| ^^^^^^^^^^^^^^^^ unconstrained const parameter
|
||||||
|
|
|
||||||
|
= note: expressions using a const parameter must map each value to a distinct output value
|
||||||
|
= note: proving the result of expressions other than the parameter are unique is not supported
|
||||||
|
|
||||||
|
error[E0284]: type annotations needed
|
||||||
|
--> $DIR/post-analysis-user-facing-param-env.rs:11:40
|
||||||
|
|
|
||||||
|
LL | fn unimplemented(self, _: &Foo) -> Self::Output {
|
||||||
|
| ^^^^^^^^^^^^ cannot infer the value of const parameter `NUM`
|
||||||
|
|
|
||||||
|
note: required for `Foo` to implement `Add<&'a Foo>`
|
||||||
|
--> $DIR/post-analysis-user-facing-param-env.rs:6:28
|
||||||
|
|
|
||||||
|
LL | impl<'a, const NUM: usize> std::ops::Add<&'a Foo> for Foo
|
||||||
|
| ---------------- ^^^^^^^^^^^^^^^^^^^^^^ ^^^
|
||||||
|
| |
|
||||||
|
| unsatisfied trait bound introduced here
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors; 1 warning emitted
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0207, E0284, E0407.
|
||||||
|
For more information about an error, try `rustc --explain E0207`.
|
Loading…
Add table
Add a link
Reference in a new issue