Skip to content

Commit 95a3dd1

Browse files
committed
Turn const eval queries in canonical queries, and add
inference context into mir execution context.
1 parent aa0769b commit 95a3dd1

File tree

30 files changed

+455
-336
lines changed

30 files changed

+455
-336
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
use crate::hir::map::DefPathHash;
5353
use crate::ich::{Fingerprint, StableHashingContext};
5454
use crate::mir;
55-
use crate::mir::interpret::GlobalId;
55+
use crate::mir::interpret::ConstEvalInput;
5656
use crate::traits;
5757
use crate::traits::query::{
5858
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,

src/librustc/infer/canonical/canonicalizer.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ use crate::infer::InferCtxt;
1313
use crate::ty::flags::FlagComputation;
1414
use crate::ty::fold::{TypeFoldable, TypeFolder};
1515
use crate::ty::subst::GenericArg;
16-
use crate::ty::{self, BoundVar, InferConst, List, Ty, TyCtxt, TypeFlags};
17-
use std::sync::atomic::Ordering;
16+
use crate::ty::{self, BoundVar, InferConst, Ty, TyCtxt, TypeFlags};
1817

1918
use rustc_data_structures::fx::FxHashMap;
2019
use rustc_index::vec::Idx;
2120
use smallvec::SmallVec;
21+
use std::sync::atomic::Ordering;
2222

2323
impl<'cx, 'tcx> InferCtxt<'cx, 'tcx> {
2424
/// Canonicalizes a query value `V`. When we canonicalize a query,
@@ -496,12 +496,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
496496

497497
// Fast path: nothing that needs to be canonicalized.
498498
if !value.has_type_flags(needs_canonical_flags) {
499-
let canon_value = Canonical {
500-
max_universe: ty::UniverseIndex::ROOT,
501-
variables: List::empty(),
502-
value: value.clone(),
503-
};
504-
return canon_value;
499+
return Canonical::empty(value.clone());
505500
}
506501

507502
let mut canonicalizer = Canonicalizer {

src/librustc/infer/canonical/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,17 @@ impl<'tcx, R> Canonical<'tcx, QueryResponse<'tcx, R>> {
266266
}
267267
}
268268

269+
impl<'tcx, V: TypeFoldable<'tcx>> Canonical<'tcx, V> {
270+
pub fn empty(value: V) -> Canonical<'tcx, V> {
271+
assert!(!value.has_local_value() && !value.has_placeholders());
272+
Canonical {
273+
max_universe: ty::UniverseIndex::ROOT,
274+
variables: List::empty(),
275+
value: value.clone(),
276+
}
277+
}
278+
}
279+
269280
impl<'tcx, V> Canonical<'tcx, V> {
270281
/// Allows you to map the `value` of a canonical while keeping the
271282
/// same set of bound variables.

src/librustc/mir/interpret/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};
115115

116116
pub use self::pointer::{CheckInAllocMsg, Pointer, PointerArithmetic};
117117

118+
use crate::infer::canonical::Canonical;
118119
use crate::mir;
119120
use crate::ty::codec::TyDecoder;
120121
use crate::ty::layout::{self, Size};
@@ -147,6 +148,8 @@ pub struct GlobalId<'tcx> {
147148
pub promoted: Option<mir::Promoted>,
148149
}
149150

151+
pub type ConstEvalInput<'tcx> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>>;
152+
150153
#[derive(Copy, Clone, Eq, Hash, Ord, PartialEq, PartialOrd, Debug)]
151154
pub struct AllocId(pub u64);
152155

src/librustc/mir/interpret/queries.rs

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use super::{ConstEvalResult, ErrorHandled, GlobalId};
22

3+
use crate::infer::canonical::{Canonical, OriginalQueryValues};
4+
use crate::infer::InferCtxt;
35
use crate::mir;
46
use crate::ty::subst::{InternalSubsts, SubstsRef};
57
use crate::ty::{self, TyCtxt};
@@ -19,7 +21,7 @@ impl<'tcx> TyCtxt<'tcx> {
1921
let instance = ty::Instance::new(def_id, substs);
2022
let cid = GlobalId { instance, promoted: None };
2123
let param_env = self.param_env(def_id).with_reveal_all();
22-
self.const_eval_validated(param_env.and(cid))
24+
self.const_eval_validated(Canonical::empty(param_env.and(cid)))
2325
}
2426

2527
/// Resolves and evaluates a constant.
@@ -38,12 +40,8 @@ impl<'tcx> TyCtxt<'tcx> {
3840
substs: SubstsRef<'tcx>,
3941
span: Option<Span>,
4042
) -> ConstEvalResult<'tcx> {
41-
let instance = ty::Instance::resolve(self, param_env, def_id, substs);
42-
if let Some(instance) = instance {
43-
self.const_eval_instance(param_env, instance, span)
44-
} else {
45-
Err(ErrorHandled::TooGeneric)
46-
}
43+
self.infer_ctxt()
44+
.enter(|ref infcx| infcx.const_eval_resolve(param_env, def_id, substs, span))
4745
}
4846

4947
pub fn const_eval_instance(
@@ -53,10 +51,11 @@ impl<'tcx> TyCtxt<'tcx> {
5351
span: Option<Span>,
5452
) -> ConstEvalResult<'tcx> {
5553
let cid = GlobalId { instance, promoted: None };
54+
let canonical = Canonical::empty(param_env.and(cid));
5655
if let Some(span) = span {
57-
self.at(span).const_eval_validated(param_env.and(cid))
56+
self.at(span).const_eval_validated(canonical)
5857
} else {
59-
self.const_eval_validated(param_env.and(cid))
58+
self.const_eval_validated(canonical)
6059
}
6160
}
6261

@@ -68,6 +67,39 @@ impl<'tcx> TyCtxt<'tcx> {
6867
) -> ConstEvalResult<'tcx> {
6968
let cid = GlobalId { instance, promoted: Some(promoted) };
7069
let param_env = ty::ParamEnv::reveal_all();
71-
self.const_eval_validated(param_env.and(cid))
70+
self.const_eval_validated(Canonical::empty(param_env.and(cid)))
71+
}
72+
}
73+
74+
impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
75+
pub fn const_eval_instance(
76+
&self,
77+
param_env: ty::ParamEnv<'tcx>,
78+
instance: ty::Instance<'tcx>,
79+
span: Option<Span>,
80+
) -> ConstEvalResult<'tcx> {
81+
let cid = GlobalId { instance, promoted: None };
82+
let mut orig_values = OriginalQueryValues::default();
83+
let canonical = self.canonicalize_query(&param_env.and(cid), &mut orig_values);
84+
if let Some(span) = span {
85+
self.tcx.at(span).const_eval_validated(canonical)
86+
} else {
87+
self.tcx.const_eval_validated(canonical)
88+
}
89+
}
90+
91+
pub fn const_eval_resolve(
92+
&self,
93+
param_env: ty::ParamEnv<'tcx>,
94+
def_id: DefId,
95+
substs: SubstsRef<'tcx>,
96+
span: Option<Span>,
97+
) -> ConstEvalResult<'tcx> {
98+
let instance = ty::Instance::resolve(self, param_env, def_id, substs);
99+
if let Some(instance) = instance {
100+
self.const_eval_instance(param_env, instance, span)
101+
} else {
102+
Err(ErrorHandled::TooGeneric)
103+
}
72104
}
73105
}

src/librustc/query/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::dep_graph::{DepKind, DepNode, RecoverKey, SerializedDepNodeIndex};
22
use crate::mir;
3-
use crate::mir::interpret::GlobalId;
3+
use crate::mir::interpret::ConstEvalInput;
44
use crate::traits;
55
use crate::traits::query::{
66
CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
@@ -467,12 +467,12 @@ rustc_queries! {
467467
/// during validation. Please add a comment to every use site explaining why using
468468
/// `const_eval_validated` isn't sufficient. The returned constant also isn't in a suitable
469469
/// form to be used outside of const eval.
470-
query const_eval_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
470+
query const_eval_raw(key: ConstEvalInput<'tcx>)
471471
-> ConstEvalRawResult<'tcx> {
472472
no_force
473473
desc { |tcx|
474474
"const-evaluating `{}`",
475-
tcx.def_path_str(key.value.instance.def.def_id())
475+
tcx.def_path_str(key.value.value.instance.def.def_id())
476476
}
477477
}
478478

@@ -484,12 +484,12 @@ rustc_queries! {
484484
///
485485
/// **Do not use this** directly, use one of the following wrappers: `tcx.const_eval_poly`,
486486
/// `tcx.const_eval_resolve`, `tcx.const_eval_instance`, or `tcx.const_eval_promoted`.
487-
query const_eval_validated(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
487+
query const_eval_validated(key: ConstEvalInput<'tcx>)
488488
-> ConstEvalResult<'tcx> {
489489
no_force
490490
desc { |tcx|
491491
"const-evaluating + checking `{}`",
492-
tcx.def_path_str(key.value.instance.def.def_id())
492+
tcx.def_path_str(key.value.value.instance.def.def_id())
493493
}
494494
cache_on_disk_if(_, opt_result) {
495495
// Only store results without errors

src/librustc/traits/fulfill.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use super::CodeSelectionError;
1515
use super::{ConstEvalFailure, Unimplemented};
1616
use super::{FulfillmentError, FulfillmentErrorCode};
1717
use super::{ObligationCause, PredicateObligation};
18+
use crate::mir::interpret::ErrorHandled;
1819

1920
impl<'tcx> ForestObligation for PendingPredicateObligation<'tcx> {
2021
type Predicate = ty::Predicate<'tcx>;
@@ -506,26 +507,19 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
506507
}
507508

508509
ty::Predicate::ConstEvaluatable(def_id, substs) => {
509-
if obligation.param_env.has_local_value() {
510-
ProcessResult::Unchanged
511-
} else {
512-
if !substs.has_local_value() {
513-
match self.selcx.tcx().const_eval_resolve(
514-
obligation.param_env,
515-
def_id,
516-
substs,
517-
Some(obligation.cause.span),
518-
) {
519-
Ok(_) => ProcessResult::Changed(vec![]),
520-
Err(err) => {
521-
ProcessResult::Error(CodeSelectionError(ConstEvalFailure(err)))
522-
}
523-
}
524-
} else {
510+
match self.selcx.infcx().const_eval_resolve(
511+
obligation.param_env,
512+
def_id,
513+
substs,
514+
Some(obligation.cause.span),
515+
) {
516+
Ok(_) => ProcessResult::Changed(vec![]),
517+
Err(ErrorHandled::TooGeneric) => {
525518
pending_obligation.stalled_on =
526519
substs.types().map(|ty| infer_ty(ty)).collect();
527520
ProcessResult::Unchanged
528521
}
522+
Err(err) => ProcessResult::Error(CodeSelectionError(ConstEvalFailure(err))),
529523
}
530524
}
531525
}

src/librustc/traits/select.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use super::{
3232
use crate::dep_graph::{DepKind, DepNodeIndex};
3333
use crate::infer::{CombinedSnapshot, InferCtxt, InferOk, PlaceholderMap, TypeFreshener};
3434
use crate::middle::lang_items;
35+
use crate::mir::interpret::ErrorHandled;
3536
use crate::ty::fast_reject;
3637
use crate::ty::relate::TypeRelation;
3738
use crate::ty::subst::{Subst, SubstsRef};
@@ -799,15 +800,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
799800
}
800801

801802
ty::Predicate::ConstEvaluatable(def_id, substs) => {
802-
if !(obligation.param_env, substs).has_local_value() {
803-
match self.tcx().const_eval_resolve(obligation.param_env, def_id, substs, None)
804-
{
805-
Ok(_) => Ok(EvaluatedToOk),
806-
Err(_) => Ok(EvaluatedToErr),
807-
}
808-
} else {
809-
// Inference variables still left in param_env or substs.
810-
Ok(EvaluatedToAmbig)
803+
match self.infcx.const_eval_resolve(
804+
obligation.param_env,
805+
def_id,
806+
substs,
807+
Some(obligation.cause.span),
808+
) {
809+
Ok(_) => Ok(EvaluatedToOk),
810+
Err(ErrorHandled::TooGeneric) => Ok(EvaluatedToAmbig),
811+
Err(_) => Ok(EvaluatedToErr),
811812
}
812813
}
813814
}

src/librustc/ty/query/keys.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,15 +199,25 @@ impl Key for Symbol {
199199
/// Canonical query goals correspond to abstract trait operations that
200200
/// are not tied to any crate in particular.
201201
impl<'tcx, T> Key for Canonical<'tcx, T> {
202-
fn query_crate(&self) -> CrateNum {
202+
default fn query_crate(&self) -> CrateNum {
203203
LOCAL_CRATE
204204
}
205205

206-
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
206+
default fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
207207
DUMMY_SP
208208
}
209209
}
210210

211+
impl<'tcx, T: Key> Key for Canonical<'tcx, T> {
212+
fn query_crate(&self) -> CrateNum {
213+
self.value.query_crate()
214+
}
215+
216+
fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
217+
self.value.default_span(tcx)
218+
}
219+
}
220+
211221
impl Key for (Symbol, u32, u32) {
212222
fn query_crate(&self) -> CrateNum {
213223
LOCAL_CRATE

src/librustc/ty/query/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ use crate::middle::region;
1313
use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
1414
use crate::middle::stability::{self, DeprecationEntry};
1515
use crate::mir;
16-
use crate::mir::interpret::GlobalId;
17-
use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult};
16+
use crate::mir::interpret::{ConstEvalInput, ConstEvalRawResult, ConstEvalResult};
1817
use crate::mir::mono::CodegenUnit;
1918
use crate::session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
2019
use crate::session::CrateDisambiguator;

0 commit comments

Comments
 (0)