make parameter-environment a query
This commit is contained in:
parent
1b7acb6f34
commit
194d4bc15d
3 changed files with 35 additions and 32 deletions
|
@ -162,6 +162,7 @@ pub enum DepNode<D: Clone + Debug> {
|
||||||
// not a hotspot.
|
// not a hotspot.
|
||||||
ProjectionCache { def_ids: Vec<D> },
|
ProjectionCache { def_ids: Vec<D> },
|
||||||
|
|
||||||
|
ParameterEnvironment(D),
|
||||||
DescribeDef(D),
|
DescribeDef(D),
|
||||||
DefSpan(D),
|
DefSpan(D),
|
||||||
Stability(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();
|
let def_ids: Option<Vec<E>> = def_ids.iter().map(op).collect();
|
||||||
def_ids.map(|d| ProjectionCache { def_ids: d })
|
def_ids.map(|d| ProjectionCache { def_ids: d })
|
||||||
}
|
}
|
||||||
|
ParameterEnvironment(ref d) => op(d).map(ParameterEnvironment),
|
||||||
DescribeDef(ref d) => op(d).map(DescribeDef),
|
DescribeDef(ref d) => op(d).map(DescribeDef),
|
||||||
DefSpan(ref d) => op(d).map(DefSpan),
|
DefSpan(ref d) => op(d).map(DefSpan),
|
||||||
Stability(ref d) => op(d).map(Stability),
|
Stability(ref d) => op(d).map(Stability),
|
||||||
|
|
|
@ -884,6 +884,8 @@ define_maps! { <'tcx>
|
||||||
[] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
|
[] specialization_graph_of: SpecializationGraph(DefId) -> Rc<specialization_graph::Graph>,
|
||||||
[] is_object_safe: ObjectSafety(DefId) -> bool,
|
[] 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()`,
|
// 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.
|
// `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,
|
[] is_copy_raw: is_copy_dep_node(ty::ParameterEnvironmentAnd<'tcx, Ty<'tcx>>) -> bool,
|
||||||
|
|
|
@ -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> {
|
pub fn node_scope_region(self, id: NodeId) -> Region<'tcx> {
|
||||||
self.mk_region(ty::ReScope(CodeExtent::Misc(id)))
|
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) {
|
pub fn provide(providers: &mut ty::maps::Providers) {
|
||||||
util::provide(providers);
|
util::provide(providers);
|
||||||
|
@ -2544,6 +2541,7 @@ pub fn provide(providers: &mut ty::maps::Providers) {
|
||||||
adt_sized_constraint,
|
adt_sized_constraint,
|
||||||
adt_dtorck_constraint,
|
adt_dtorck_constraint,
|
||||||
def_span,
|
def_span,
|
||||||
|
parameter_environment,
|
||||||
trait_of_item,
|
trait_of_item,
|
||||||
trait_impls_of: trait_def::trait_impls_of_provider,
|
trait_impls_of: trait_def::trait_impls_of_provider,
|
||||||
relevant_trait_impls_for: trait_def::relevant_trait_impls_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,
|
adt_dtorck_constraint,
|
||||||
trait_impls_of: trait_def::trait_impls_of_provider,
|
trait_impls_of: trait_def::trait_impls_of_provider,
|
||||||
relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
|
relevant_trait_impls_for: trait_def::relevant_trait_impls_provider,
|
||||||
|
parameter_environment,
|
||||||
..*providers
|
..*providers
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue