Skip to content

Commit 3a50b41

Browse files
committed
introduce infcx.at(..).normalize(..) operation [VIC]
It is backed by the new `normalize_projection_ty` query, which uses canonicalization.
1 parent 8c024fd commit 3a50b41

File tree

23 files changed

+637
-10
lines changed

23 files changed

+637
-10
lines changed

src/Cargo.lock

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc/dep_graph/dep_node.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,12 @@ use hir::{HirId, ItemLocalId};
6767

6868
use ich::{Fingerprint, StableHashingContext};
6969
use rustc_data_structures::stable_hasher::{StableHasher, HashStable};
70-
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
71-
use ty::subst::Substs;
7270
use std::fmt;
7371
use std::hash::Hash;
7472
use syntax_pos::symbol::InternedString;
73+
use traits::query::CanonicalProjectionGoal;
74+
use ty::{TyCtxt, Instance, InstanceDef, ParamEnv, ParamEnvAnd, PolyTraitRef, Ty};
75+
use ty::subst::Substs;
7576

7677
// erase!() just makes tokens go away. It's used to specify which macro argument
7778
// 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>
635636
[] CompileCodegenUnit(InternedString),
636637
[input] OutputFilenames,
637638
[anon] NormalizeTy,
639+
[] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>),
638640

639641
[] SubstituteNormalizeAndTestPredicates { key: (DefId, &'tcx Substs<'tcx>) },
640642

src/librustc/infer/at.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ use super::*;
4040
use ty::relate::{Relate, TypeRelation};
4141

4242
pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
43-
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
44-
cause: &'a ObligationCause<'tcx>,
45-
param_env: ty::ParamEnv<'tcx>,
43+
pub infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
44+
pub cause: &'a ObligationCause<'tcx>,
45+
pub param_env: ty::ParamEnv<'tcx>,
4646
}
4747

4848
pub struct Trace<'a, 'gcx: 'tcx, 'tcx: 'a> {

src/librustc/infer/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ pub mod type_variable;
6969
pub mod unify_key;
7070

7171
#[must_use]
72+
#[derive(Debug)]
7273
pub struct InferOk<'tcx, T> {
7374
pub value: T,
7475
pub obligations: PredicateObligations<'tcx>,
@@ -1224,6 +1225,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
12241225
self.borrow_region_constraints().take_and_reset_data()
12251226
}
12261227

1228+
/// Gives temporary access to the region constraint data.
1229+
#[allow(non_camel_case_types)] // bug with impl trait
1230+
pub fn with_region_constraints<R>(
1231+
&self,
1232+
op: impl FnOnce(&RegionConstraintData<'tcx>) -> R,
1233+
) -> R {
1234+
let region_constraints = self.borrow_region_constraints();
1235+
op(region_constraints.data())
1236+
}
1237+
12271238
/// Takes ownership of the list of variable regions. This implies
12281239
/// that all the region constriants have already been taken, and
12291240
/// hence that `resolve_regions_and_report_errors` can never be

src/librustc/infer/outlives/obligations.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,16 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
9999
.push((body_id, obligation));
100100
}
101101

102+
/// Trait queries just want to pass back type obligations "as is"
103+
pub fn take_registered_region_obligations(
104+
&self,
105+
) -> Vec<(ast::NodeId, RegionObligation<'tcx>)> {
106+
::std::mem::replace(
107+
&mut *self.region_obligations.borrow_mut(),
108+
vec![],
109+
)
110+
}
111+
102112
/// Process the region obligations that must be proven (during
103113
/// `regionck`) for the given `body_id`, given information about
104114
/// the region bounds in scope and so forth. This function must be

src/librustc/infer/region_constraints/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,10 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
350350
mem::replace(data, RegionConstraintData::default())
351351
}
352352

353+
pub fn data(&self) -> &RegionConstraintData<'tcx> {
354+
&self.data
355+
}
356+
353357
fn in_snapshot(&self) -> bool {
354358
!self.undo_log.is_empty()
355359
}

src/librustc/session/mod.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,11 @@ pub struct PerfStats {
175175
pub decode_def_path_tables_time: Cell<Duration>,
176176
/// Total number of values canonicalized queries constructed.
177177
pub queries_canonicalized: Cell<usize>,
178+
/// Number of times we canonicalized a value and found that the
179+
/// result had already been canonicalized.
180+
pub canonicalized_values_allocated: Cell<usize>,
181+
/// Number of times this query is invoked.
182+
pub normalize_projection_ty: Cell<usize>,
178183
}
179184

180185
/// Enum to support dispatch of one-time diagnostics (in Session.diag_once)
@@ -862,6 +867,10 @@ impl Session {
862867
);
863868
println!("Total queries canonicalized: {}",
864869
self.perf_stats.queries_canonicalized.get());
870+
println!("Total canonical values interned: {}",
871+
self.perf_stats.canonicalized_values_allocated.get());
872+
println!("normalize_projection_ty: {}",
873+
self.perf_stats.normalize_projection_ty.get());
865874
}
866875

867876
/// 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_(
11491158
symbol_hash_time: Cell::new(Duration::from_secs(0)),
11501159
decode_def_path_tables_time: Cell::new(Duration::from_secs(0)),
11511160
queries_canonicalized: Cell::new(0),
1161+
canonicalized_values_allocated: Cell::new(0),
1162+
normalize_projection_ty: Cell::new(0),
11521163
},
11531164
code_stats: RefCell::new(CodeStats::new()),
11541165
optimization_fuel_crate,

src/librustc/traits/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ mod structural_impls;
6363
pub mod trans;
6464
mod util;
6565

66+
pub mod query;
67+
6668
// Whether to enable bug compatibility with issue #43355
6769
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
6870
pub enum IntercrateMode {

src/librustc/traits/query/mod.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
//! Experimental types for the trait query interface. The methods
12+
//! defined in this module are all based on **canonicalization**,
13+
//! which makes a canonical query by replacing unbound inference
14+
//! variables and regions, so that results can be reused more broadly.
15+
//! The providers for the queries defined here can be found in
16+
//! `librustc_traits`.
17+
18+
use infer::canonical::Canonical;
19+
use ty;
20+
21+
pub mod normalize;
22+
23+
pub type CanonicalProjectionGoal<'tcx> =
24+
Canonical<'tcx, ty::ParamEnvAnd<'tcx, ty::ProjectionTy<'tcx>>>;
25+
26+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
27+
pub struct NoSolution;
28+
29+
pub type Fallible<T> = Result<T, NoSolution>;
30+
31+
impl_stable_hash_for!(struct NoSolution { });

0 commit comments

Comments
 (0)