introduce infcx.at(..).normalize(..) operation [VIC]
It is backed by the new `normalize_projection_ty` query, which uses canonicalization.
This commit is contained in:
parent
8c024fdafb
commit
3a50b41da4
23 changed files with 637 additions and 10 deletions
|
|
@ -67,11 +67,12 @@ use hir::{HirId, ItemLocalId};
|
|||
|
||||
use ich::{Fingerprint, StableHashingContext};
|
||||
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
|
||||
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
|
||||
use ty::subst::Substs;
|
||||
use std::fmt;
|
||||
use std::hash::Hash;
|
||||
use syntax_pos::symbol::InternedString;
|
||||
use traits::query::CanonicalProjectionGoal;
|
||||
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
|
||||
use ty::subst::Substs;
|
||||
|
||||
// erase!() just makes tokens go away. It's used to specify which macro argument
|
||||
// is repeated (i.e. which sub-expression of the macro we are in) but don't need
|
||||
|
|
@ -635,6 +636,7 @@ define_dep_nodes!( <'tcx>
|
|||
[] CompileCodegenUnit(InternedString),
|
||||
[input] OutputFilenames,
|
||||
[anon] NormalizeTy,
|
||||
[] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>),
|
||||
|
||||
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
|
||||
|
||||
|
|
|
|||
|
|
@ -40,9 +40,9 @@ use super::*;
|
|||
use ty::relate::{Relate, TypeRelation};
|
||||
|
||||
pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
cause: &'a ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
|
||||
pub cause: &'a ObligationCause<'tcx>,
|
||||
pub param_env: ty::ParamEnv<'tcx>,
|
||||
}
|
||||
|
||||
pub struct Trace<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ pub mod type_variable;
|
|||
pub mod unify_key;
|
||||
|
||||
#[must_use]
|
||||
#[derive(Debug)]
|
||||
pub struct InferOk<'tcx, T> {
|
||||
pub value: T,
|
||||
pub obligations: PredicateObligations<'tcx>,
|
||||
|
|
@ -1224,6 +1225,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||
self.borrow_region_constraints().take_and_reset_data()
|
||||
}
|
||||
|
||||
/// Gives temporary access to the region constraint data.
|
||||
#[allow(non_camel_case_types)] // bug with impl trait
|
||||
pub fn with_region_constraints<R>(
|
||||
&self,
|
||||
op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,
|
||||
) -> R {
|
||||
let region_constraints = self.borrow_region_constraints();
|
||||
op(region_constraints.data())
|
||||
}
|
||||
|
||||
/// Takes ownership of the list of variable regions. This implies
|
||||
/// that all the region constriants have already been taken, and
|
||||
/// hence that `resolve_regions_and_report_errors` can never be
|
||||
|
|
|
|||
|
|
@ -99,6 +99,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
|
|||
.push((body_id, obligation));
|
||||
}
|
||||
|
||||
/// Trait queries just want to pass back type obligations "as is"
|
||||
pub fn take_registered_region_obligations(
|
||||
&self,
|
||||
) -> Vec<(ast::NodeId, RegionObligation<'tcx>)> {
|
||||
::std::mem::replace(
|
||||
&mut *self.region_obligations.borrow_mut(),
|
||||
vec![],
|
||||
)
|
||||
}
|
||||
|
||||
/// Process the region obligations that must be proven (during
|
||||
/// `regionck`) for the given `body_id`, given information about
|
||||
/// the region bounds in scope and so forth. This function must be
|
||||
|
|
|
|||
|
|
@ -350,6 +350,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
|||
mem::replace(data, RegionConstraintData::default())
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &RegionConstraintData<'tcx> {
|
||||
&self.data
|
||||
}
|
||||
|
||||
fn in_snapshot(&self) -> bool {
|
||||
!self.undo_log.is_empty()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,6 +175,11 @@ pub struct PerfStats {
|
|||
pub decode_def_path_tables_time: Cell<Duration>,
|
||||
/// Total number of values canonicalized queries constructed.
|
||||
pub queries_canonicalized: Cell<usize>,
|
||||
/// Number of times we canonicalized a value and found that the
|
||||
/// result had already been canonicalized.
|
||||
pub canonicalized_values_allocated: Cell<usize>,
|
||||
/// Number of times this query is invoked.
|
||||
pub normalize_projection_ty: Cell<usize>,
|
||||
}
|
||||
|
||||
/// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
|
||||
|
|
@ -862,6 +867,10 @@ impl Session {
|
|||
);
|
||||
println!("Total queries canonicalized: {}",
|
||||
self.perf_stats.queries_canonicalized.get());
|
||||
println!("Total canonical values interned: {}",
|
||||
self.perf_stats.canonicalized_values_allocated.get());
|
||||
println!("normalize_projection_ty: {}",
|
||||
self.perf_stats.normalize_projection_ty.get());
|
||||
}
|
||||
|
||||
/// We want to know if we're allowed to do an optimization for crate foo from -z fuel=foo=n.
|
||||
|
|
@ -1149,6 +1158,8 @@ pub fn build_session_(
|
|||
symbol_hash_time: Cell::new(Duration::from_secs(0)),
|
||||
decode_def_path_tables_time: Cell::new(Duration::from_secs(0)),
|
||||
queries_canonicalized: Cell::new(0),
|
||||
canonicalized_values_allocated: Cell::new(0),
|
||||
normalize_projection_ty: Cell::new(0),
|
||||
},
|
||||
code_stats: RefCell::new(CodeStats::new()),
|
||||
optimization_fuel_crate,
|
||||
|
|
|
|||
|
|
@ -63,6 +63,8 @@ mod structural_impls;
|
|||
pub mod trans;
|
||||
mod util;
|
||||
|
||||
pub mod query;
|
||||
|
||||
// Whether to enable bug compatibility with issue #43355
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum IntercrateMode {
|
||||
|
|
|
|||
31
src/librustc/traits/query/mod.rs
Normal file
31
src/librustc/traits/query/mod.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Experimental types for the trait query interface. The methods
|
||||
//! defined in this module are all based on **canonicalization**,
|
||||
//! which makes a canonical query by replacing unbound inference
|
||||
//! variables and regions, so that results can be reused more broadly.
|
||||
//! The providers for the queries defined here can be found in
|
||||
//! `librustc_traits`.
|
||||
|
||||
use infer::canonical::Canonical;
|
||||
use ty;
|
||||
|
||||
pub mod normalize;
|
||||
|
||||
pub type CanonicalProjectionGoal<'tcx> =
|
||||
Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>;
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct NoSolution;
|
||||
|
||||
pub type Fallible<T> = Result<T, NoSolution>;
|
||||
|
||||
impl_stable_hash_for!(struct NoSolution { });
|
||||
268
src/librustc/traits/query/normalize.rs
Normal file
268
src/librustc/traits/query/normalize.rs
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
//! Code for the 'normalization' query. This consists of a wrapper
|
||||
//! which folds deeply, invoking the underlying
|
||||
//! `normalize_projection_ty` query when it encounters projections.
|
||||
|
||||
use infer::{InferCtxt, InferOk};
|
||||
use infer::at::At;
|
||||
use infer::canonical::{Canonical, Canonicalize, QueryResult};
|
||||
use middle::const_val::ConstVal;
|
||||
use mir::interpret::GlobalId;
|
||||
use std::rc::Rc;
|
||||
use traits::{Obligation, ObligationCause, PredicateObligation, Reveal};
|
||||
use traits::query::CanonicalProjectionGoal;
|
||||
use traits::project::Normalized;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::fold::{TypeFoldable, TypeFolder};
|
||||
use ty::subst::{Subst, Substs};
|
||||
|
||||
use super::NoSolution;
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
|
||||
/// Normalize `value` in the context of the inference context,
|
||||
/// yielding a resulting type, or an error if `value` cannot be
|
||||
/// normalized. If you don't care about regions, you should prefer
|
||||
/// `normalize_erasing_regions`, which is more efficient.
|
||||
///
|
||||
/// If the normalization succeeds and is unambigious, returns back
|
||||
/// the normalized value along with various outlives relations (in
|
||||
/// the form of obligations that must be discharged).
|
||||
///
|
||||
/// NB. This will *eventually* be the main means of
|
||||
/// normalizing, but for now should be used only when we actually
|
||||
/// know that normalization will succeed, since error reporting
|
||||
/// and other details are still "under development".
|
||||
pub fn normalize<T>(&self, value: &T) -> Result<Normalized<'tcx, T>, NoSolution>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
{
|
||||
let mut normalizer = QueryNormalizer {
|
||||
infcx: self.infcx,
|
||||
cause: self.cause,
|
||||
param_env: self.param_env,
|
||||
obligations: vec![],
|
||||
error: false,
|
||||
anon_depth: 0,
|
||||
};
|
||||
if !value.has_projections() {
|
||||
return Ok(Normalized {
|
||||
value: value.clone(),
|
||||
obligations: vec![],
|
||||
});
|
||||
}
|
||||
|
||||
let value1 = value.fold_with(&mut normalizer);
|
||||
if normalizer.error {
|
||||
Err(NoSolution)
|
||||
} else {
|
||||
Ok(Normalized {
|
||||
value: value1,
|
||||
obligations: normalizer.obligations,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Result from the `normalize_projection_ty` query.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct NormalizationResult<'tcx> {
|
||||
/// Result of normalization.
|
||||
pub normalized_ty: Ty<'tcx>,
|
||||
}
|
||||
|
||||
struct QueryNormalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
|
||||
infcx: &'cx InferCtxt<'cx, 'gcx, 'tcx>,
|
||||
cause: &'cx ObligationCause<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
obligations: Vec<PredicateObligation<'tcx>>,
|
||||
error: bool,
|
||||
anon_depth: usize,
|
||||
}
|
||||
|
||||
impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for QueryNormalizer<'cx, 'gcx, 'tcx> {
|
||||
fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
|
||||
let ty = ty.super_fold_with(self);
|
||||
match ty.sty {
|
||||
ty::TyAnon(def_id, substs) if !substs.has_escaping_regions() => {
|
||||
// (*)
|
||||
// Only normalize `impl Trait` after type-checking, usually in trans.
|
||||
match self.param_env.reveal {
|
||||
Reveal::UserFacing => ty,
|
||||
|
||||
Reveal::All => {
|
||||
let recursion_limit = self.tcx().sess.recursion_limit.get();
|
||||
if self.anon_depth >= recursion_limit {
|
||||
let obligation = Obligation::with_depth(
|
||||
self.cause.clone(),
|
||||
recursion_limit,
|
||||
self.param_env,
|
||||
ty,
|
||||
);
|
||||
self.infcx.report_overflow_error(&obligation, true);
|
||||
}
|
||||
|
||||
let generic_ty = self.tcx().type_of(def_id);
|
||||
let concrete_ty = generic_ty.subst(self.tcx(), substs);
|
||||
self.anon_depth += 1;
|
||||
let folded_ty = self.fold_ty(concrete_ty);
|
||||
self.anon_depth -= 1;
|
||||
folded_ty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ty::TyProjection(ref data) if !data.has_escaping_regions() => {
|
||||
// (*)
|
||||
// (*) This is kind of hacky -- we need to be able to
|
||||
// handle normalization within binders because
|
||||
// otherwise we wind up a need to normalize when doing
|
||||
// trait matching (since you can have a trait
|
||||
// obligation like `for<'a> T::B : Fn(&'a int)`), but
|
||||
// we can't normalize with bound regions in scope. So
|
||||
// far now we just ignore binders but only normalize
|
||||
// if all bound regions are gone (and then we still
|
||||
// have to renormalize whenever we instantiate a
|
||||
// binder). It would be better to normalize in a
|
||||
// binding-aware fashion.
|
||||
|
||||
let gcx = self.infcx.tcx.global_tcx();
|
||||
|
||||
let (c_data, orig_values) =
|
||||
self.infcx.canonicalize_query(&self.param_env.and(*data));
|
||||
debug!("QueryNormalizer: c_data = {:#?}", c_data);
|
||||
debug!("QueryNormalizer: orig_values = {:#?}", orig_values);
|
||||
match gcx.normalize_projection_ty(c_data) {
|
||||
Ok(result) => {
|
||||
// We don't expect ambiguity.
|
||||
if result.is_ambiguous() {
|
||||
self.error = true;
|
||||
return ty;
|
||||
}
|
||||
|
||||
match self.infcx.instantiate_query_result(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
&result,
|
||||
) {
|
||||
Ok(InferOk {
|
||||
value: result,
|
||||
obligations,
|
||||
}) => {
|
||||
debug!("QueryNormalizer: result = {:#?}", result);
|
||||
debug!("QueryNormalizer: obligations = {:#?}", obligations);
|
||||
self.obligations.extend(obligations);
|
||||
return result.normalized_ty;
|
||||
}
|
||||
|
||||
Err(_) => {
|
||||
self.error = true;
|
||||
return ty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(NoSolution) => {
|
||||
self.error = true;
|
||||
ty
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_ => ty,
|
||||
}
|
||||
}
|
||||
|
||||
fn fold_const(&mut self, constant: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
if let ConstVal::Unevaluated(def_id, substs) = constant.val {
|
||||
let tcx = self.infcx.tcx.global_tcx();
|
||||
if let Some(param_env) = self.tcx().lift_to_global(&self.param_env) {
|
||||
if substs.needs_infer() {
|
||||
let identity_substs = Substs::identity_for_item(tcx, def_id);
|
||||
let instance = ty::Instance::resolve(tcx, param_env, def_id, identity_substs);
|
||||
if let Some(instance) = instance {
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
match tcx.const_eval(param_env.and(cid)) {
|
||||
Ok(evaluated) => {
|
||||
let evaluated = evaluated.subst(self.tcx(), substs);
|
||||
return self.fold_const(evaluated);
|
||||
}
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if let Some(substs) = self.tcx().lift_to_global(&substs) {
|
||||
let instance = ty::Instance::resolve(tcx, param_env, def_id, substs);
|
||||
if let Some(instance) = instance {
|
||||
let cid = GlobalId {
|
||||
instance,
|
||||
promoted: None,
|
||||
};
|
||||
match tcx.const_eval(param_env.and(cid)) {
|
||||
Ok(evaluated) => return self.fold_const(evaluated),
|
||||
Err(_) => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
constant
|
||||
}
|
||||
}
|
||||
|
||||
BraceStructTypeFoldableImpl! {
|
||||
impl<'tcx> TypeFoldable<'tcx> for NormalizationResult<'tcx> {
|
||||
normalized_ty
|
||||
}
|
||||
}
|
||||
|
||||
BraceStructLiftImpl! {
|
||||
impl<'a, 'tcx> Lift<'tcx> for NormalizationResult<'a> {
|
||||
type Lifted = NormalizationResult<'tcx>;
|
||||
normalized_ty
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>> {
|
||||
type Canonicalized = CanonicalProjectionGoal<'gcx>;
|
||||
|
||||
fn intern(
|
||||
_gcx: TyCtxt<'_, 'gcx, 'gcx>,
|
||||
value: Canonical<'gcx, Self::Lifted>,
|
||||
) -> Self::Canonicalized {
|
||||
value
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gcx: 'tcx, 'tcx> Canonicalize<'gcx, 'tcx> for QueryResult<'tcx, NormalizationResult<'tcx>> {
|
||||
// we ought to intern this, but I'm too lazy just now
|
||||
type Canonicalized = Rc<Canonical<'gcx, QueryResult<'gcx, NormalizationResult<'gcx>>>>;
|
||||
|
||||
fn intern(
|
||||
_gcx: TyCtxt<'_, 'gcx, 'gcx>,
|
||||
value: Canonical<'gcx, Self::Lifted>,
|
||||
) -> Self::Canonicalized {
|
||||
Rc::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl_stable_hash_for!(struct NormalizationResult<'tcx> {
|
||||
normalized_ty
|
||||
});
|
||||
|
|
@ -106,6 +106,7 @@ pub struct GlobalArenas<'tcx> {
|
|||
tables: TypedArena<ty::TypeckTables<'tcx>>,
|
||||
/// miri allocations
|
||||
const_allocs: TypedArena<interpret::Allocation>,
|
||||
|
||||
}
|
||||
|
||||
impl<'tcx> GlobalArenas<'tcx> {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
use dep_graph::SerializedDepNodeIndex;
|
||||
use hir::def_id::{CrateNum, DefId, DefIndex};
|
||||
use mir::interpret::{GlobalId};
|
||||
use traits::query::CanonicalProjectionGoal;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::subst::Substs;
|
||||
use ty::maps::queries;
|
||||
|
|
@ -51,6 +52,15 @@ impl<'tcx, M: QueryConfig<Key=DefId>> QueryDescription<'tcx> for M {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription<'tcx> for queries::normalize_projection_ty<'tcx> {
|
||||
fn describe(
|
||||
_tcx: TyCtxt,
|
||||
goal: CanonicalProjectionGoal<'tcx>,
|
||||
) -> String {
|
||||
format!("normalizing `{:?}`", goal)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QueryDescription<'tcx> for queries::is_copy_raw<'tcx> {
|
||||
fn describe(_tcx: TyCtxt, env: ty::ParamEnvAnd<'tcx, Ty<'tcx>>) -> String {
|
||||
format!("computing whether `{}` is `Copy`", env.value)
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
//! Defines the set of legal keys that can be used in queries.
|
||||
|
||||
use hir::def_id::{CrateNum, DefId, LOCAL_CRATE, DefIndex};
|
||||
use traits::query::CanonicalProjectionGoal;
|
||||
use ty::{self, Ty, TyCtxt};
|
||||
use ty::subst::Substs;
|
||||
use ty::fast_reject::SimplifiedType;
|
||||
|
|
@ -170,3 +171,13 @@ impl Key for InternedString {
|
|||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for CanonicalProjectionGoal<'tcx> {
|
||||
fn map_crate(&self) -> CrateNum {
|
||||
LOCAL_CRATE
|
||||
}
|
||||
|
||||
fn default_span(&self, _tcx: TyCtxt) -> Span {
|
||||
DUMMY_SP
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use hir::def_id::{CrateNum, DefId, DefIndex};
|
|||
use hir::def::{Def, Export};
|
||||
use hir::{self, TraitCandidate, ItemLocalId, TransFnAttrs};
|
||||
use hir::svh::Svh;
|
||||
use infer::canonical::{Canonical, QueryResult};
|
||||
use lint;
|
||||
use middle::borrowck::BorrowCheckResult;
|
||||
use middle::cstore::{ExternCrate, LinkagePreference, NativeLibrary,
|
||||
|
|
@ -33,6 +34,8 @@ use mir::interpret::{GlobalId};
|
|||
use session::{CompileResult, CrateDisambiguator};
|
||||
use session::config::OutputFilenames;
|
||||
use traits::Vtable;
|
||||
use traits::query::{CanonicalProjectionGoal, NoSolution};
|
||||
use traits::query::normalize::NormalizationResult;
|
||||
use traits::specialization_graph;
|
||||
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
|
||||
use ty::steal::Steal;
|
||||
|
|
@ -380,6 +383,14 @@ define_maps! { <'tcx>
|
|||
[] fn erase_regions_ty: erase_regions_ty(Ty<'tcx>) -> Ty<'tcx>,
|
||||
[] fn fully_normalize_monormophic_ty: normalize_ty_node(Ty<'tcx>) -> Ty<'tcx>,
|
||||
|
||||
/// Do not call this query directly: invoke `normalize` instead.
|
||||
[] fn normalize_projection_ty: NormalizeProjectionTy(
|
||||
CanonicalProjectionGoal<'tcx>
|
||||
) -> Result<
|
||||
Lrc<Canonical<'tcx, QueryResult<'tcx, NormalizationResult<'tcx>>>>,
|
||||
NoSolution,
|
||||
>,
|
||||
|
||||
[] fn substitute_normalize_and_test_predicates:
|
||||
substitute_normalize_and_test_predicates_node((DefId, &'tcx Substs<'tcx>)) -> bool,
|
||||
|
||||
|
|
@ -537,6 +548,7 @@ fn output_filenames_node<'tcx>(_: CrateNum) -> DepConstructor<'tcx> {
|
|||
fn vtable_methods_node<'tcx>(trait_ref: ty::PolyTraitRef<'tcx>) -> DepConstructor<'tcx> {
|
||||
DepConstructor::VtableMethods{ trait_ref }
|
||||
}
|
||||
|
||||
fn normalize_ty_node<'tcx>(_: Ty<'tcx>) -> DepConstructor<'tcx> {
|
||||
DepConstructor::NormalizeTy
|
||||
}
|
||||
|
|
|
|||
|
|
@ -773,6 +773,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
|
|||
DepKind::VtableMethods |
|
||||
DepKind::EraseRegionsTy |
|
||||
DepKind::NormalizeTy |
|
||||
DepKind::NormalizeProjectionTy |
|
||||
DepKind::SubstituteNormalizeAndTestPredicates |
|
||||
DepKind::InstanceDefSizeEstimate |
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue