1
Fork 0

make parameter-environment a query

This commit is contained in:
Niko Matsakis 2017-05-11 17:40:03 -04:00
parent 1b7acb6f34
commit 194d4bc15d
3 changed files with 35 additions and 32 deletions

View file

@ -162,6 +162,7 @@ pub enum DepNode<D: Clone + Debug> {
// not a hotspot.
ProjectionCache { def_ids: Vec<D> },
ParameterEnvironment(D),
DescribeDef(D),
DefSpan(D),
Stability(D),
@ -290,6 +291,7 @@ impl<D: Clone + Debug> DepNode<D> {
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
def_ids.map(|d| ProjectionCache { def_ids: d })
}
ParameterEnvironment(ref d) => op(d).map(ParameterEnvironment),
DescribeDef(ref d) => op(d).map(DescribeDef),
DefSpan(ref d) => op(d).map(DefSpan),
Stability(ref d) => op(d).map(Stability),

View file

@ -884,6 +884,8 @@ define_maps! { <'tcx>
[] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
[] is_object_safe: ObjectSafety(DefId) -> bool,
[] parameter_environment: ParameterEnvironment(DefId) -> ty::ParameterEnvironment<'tcx>,
// Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
// `ty.is_copy()`, etc, since that will prune the environment where possible.
[] is_copy_raw: is_copy_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool,

View file

@ -2344,38 +2344,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
}
}
/// See `ParameterEnvironment` struct def'n for details.
pub fn parameter_environment(self, def_id: DefId) -> ParameterEnvironment<'gcx> {
//
// Compute the bounds on Self and the type parameters.
//
let tcx = self.global_tcx();
let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
let predicates = bounds.predicates;
// Finally, we have to normalize the bounds in the environment, in
// case they contain any associated type projections. This process
// can yield errors if the put in illegal associated types, like
// `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
// report these errors right here; this doesn't actually feel
// right to me, because constructing the environment feels like a
// kind of a "idempotent" action, but I'm not sure where would be
// a better place. In practice, we construct environments for
// every fn once during type checking, and we'll abort if there
// are any errors at that point, so after type checking you can be
// sure that this will succeed without errors anyway.
//
let unnormalized_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates));
let body_id = self.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
self.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
});
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
}
pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> {
self.mk_region(ty::ReScope(CodeExtent::Misc(id)))
}
@ -2535,6 +2503,35 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
})
}
/// See `ParameterEnvironment` struct def'n for details.
fn parameter_environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId)
-> ParameterEnvironment<'tcx> {
// Compute the bounds on Self and the type parameters.
let bounds = tcx.predicates_of(def_id).instantiate_identity(tcx);
let predicates = bounds.predicates;
// Finally, we have to normalize the bounds in the environment, in
// case they contain any associated type projections. This process
// can yield errors if the put in illegal associated types, like
// `<i32 as Foo>::Bar` where `i32` does not implement `Foo`. We
// report these errors right here; this doesn't actually feel
// right to me, because constructing the environment feels like a
// kind of a "idempotent" action, but I'm not sure where would be
// a better place. In practice, we construct environments for
// every fn once during type checking, and we'll abort if there
// are any errors at that point, so after type checking you can be
// sure that this will succeed without errors anyway.
let unnormalized_env = ty::ParameterEnvironment::new(tcx.intern_predicates(&predicates));
let body_id = tcx.hir.as_local_node_id(def_id).map_or(DUMMY_NODE_ID, |id| {
tcx.hir.maybe_body_owned_by(id).map_or(id, |body| body.node_id)
});
let cause = traits::ObligationCause::misc(tcx.def_span(def_id), body_id);
traits::normalize_param_env_or_error(tcx, def_id, unnormalized_env, cause)
}
pub fn provide(providers: &mut ty::maps::Providers) {
util::provide(providers);
@ -2544,6 +2541,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
adt_sized_constraint,
adt_dtorck_constraint,
def_span,
parameter_environment,
trait_of_item,
trait_impls_of: trait_def::trait_impls_of_provider,
relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
@ -2557,6 +2555,7 @@ pub fn provide_extern(providers: &mut ty::maps::Providers) {
adt_dtorck_constraint,
trait_impls_of: trait_def::trait_impls_of_provider,
relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
parameter_environment,
..*providers
};
}