Skip to content

Commit

Permalink
introduce infcx.at(..).normalize(..) operation [VIC]
Browse files Browse the repository at this point in the history
It is backed by the new `normalize_projection_ty` query, which uses
canonicalization.
  • Loading branch information
nikomatsakis committed Mar 13, 2018
1 parent 8c024fd commit 3a50b41
Show file tree
Hide file tree
Showing 23 changed files with 637 additions and 10 deletions.
14 changes: 14 additions & 0 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/librustc/dep_graph/dep_node.rs
Expand Up @@ -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
Expand Down Expand Up @@ -635,6 +636,7 @@ define_dep_nodes!( <'tcx>
[] CompileCodegenUnit(InternedString),
[input] OutputFilenames,
[anon] NormalizeTy,
[] NormalizeProjectionTy(CanonicalProjectionGoal<'tcx>),

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

Expand Down
6 changes: 3 additions & 3 deletions src/librustc/infer/at.rs
Expand Up @@ -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> {
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/infer/mod.rs
Expand Up @@ -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>,
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions src/librustc/infer/outlives/obligations.rs
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions src/librustc/infer/region_constraints/mod.rs
Expand Up @@ -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()
}
Expand Down
11 changes: 11 additions & 0 deletions src/librustc/session/mod.rs
Expand Up @@ -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)
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/traits/mod.rs
Expand Up @@ -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 {
Expand Down
31 changes: 31 additions & 0 deletions src/librustc/traits/query/mod.rs
@@ -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 { });

0 comments on commit 3a50b41

Please sign in to comment.