mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
Return an instantiated environment instead of a generic one
This commit is contained in:
parent
8cadd59674
commit
ec7362442c
@ -684,7 +684,7 @@ define_queries! { <'tcx>
|
||||
) -> Clauses<'tcx>,
|
||||
|
||||
// Get the chalk-style environment of the given item.
|
||||
[] fn environment: Environment(DefId) -> ty::Binder<traits::Environment<'tcx>>,
|
||||
[] fn environment: Environment(DefId) -> traits::Environment<'tcx>,
|
||||
},
|
||||
|
||||
Linking {
|
||||
|
@ -256,6 +256,8 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
|
||||
) -> Vec<Clause<'tcx>> {
|
||||
use rustc::traits::WhereClause::*;
|
||||
|
||||
debug!("program_clauses(goal = {:?})", goal);
|
||||
|
||||
let mut clauses = match goal {
|
||||
DomainGoal::Holds(Implemented(trait_predicate)) => {
|
||||
// These come from:
|
||||
@ -345,20 +347,21 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
|
||||
self.infcx.tcx.program_clauses_for(data.item_def_id)
|
||||
}
|
||||
|
||||
// These types are always WF and non-parametric.
|
||||
// These types are always WF.
|
||||
ty::Bool |
|
||||
ty::Char |
|
||||
ty::Int(..) |
|
||||
ty::Uint(..) |
|
||||
ty::Float(..) |
|
||||
ty::Str |
|
||||
ty::Param(..) |
|
||||
ty::Never => {
|
||||
let wf_clause = ProgramClause {
|
||||
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
|
||||
hypotheses: ty::List::empty(),
|
||||
category: ProgramClauseCategory::WellFormed,
|
||||
};
|
||||
let wf_clause = Clause::ForAll(ty::Binder::dummy(wf_clause));
|
||||
let wf_clause = Clause::Implies(wf_clause);
|
||||
|
||||
self.infcx.tcx.mk_clauses(iter::once(wf_clause))
|
||||
}
|
||||
@ -415,7 +418,6 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Infer(..) |
|
||||
ty::Bound(..) |
|
||||
ty::Param(..) |
|
||||
ty::Error => {
|
||||
bug!("unexpected type {:?}", ty)
|
||||
}
|
||||
@ -458,13 +460,18 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
|
||||
}
|
||||
};
|
||||
|
||||
debug!("program_clauses: clauses = {:?}", clauses);
|
||||
debug!("program_clauses: adding clauses from environment = {:?}", environment);
|
||||
|
||||
let environment = self.infcx.tcx.lift_to_global(environment)
|
||||
.expect("environment is not global");
|
||||
clauses.extend(
|
||||
self.infcx.tcx.program_clauses_for_env(environment)
|
||||
.into_iter()
|
||||
.cloned()
|
||||
);
|
||||
|
||||
let env_clauses = self.infcx.tcx.program_clauses_for_env(environment);
|
||||
|
||||
debug!("program_clauses: env_clauses = {:?}", env_clauses);
|
||||
|
||||
clauses.extend(env_clauses.into_iter().cloned());
|
||||
clauses.extend(environment.clauses.iter().cloned());
|
||||
clauses
|
||||
}
|
||||
}
|
||||
|
@ -105,11 +105,11 @@ impl ClauseVisitor<'set, 'a, 'tcx> {
|
||||
ty::Never |
|
||||
ty::Infer(..) |
|
||||
ty::Placeholder(..) |
|
||||
ty::Param(..) |
|
||||
ty::Bound(..) => (),
|
||||
|
||||
ty::GeneratorWitness(..) |
|
||||
ty::UnnormalizedProjection(..) |
|
||||
ty::Param(..) |
|
||||
ty::Error => {
|
||||
bug!("unexpected type {:?}", ty);
|
||||
}
|
||||
@ -192,25 +192,23 @@ crate fn program_clauses_for_env<'a, 'tcx>(
|
||||
crate fn environment<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
def_id: DefId
|
||||
) -> ty::Binder<Environment<'tcx>> {
|
||||
) -> Environment<'tcx> {
|
||||
use super::{Lower, IntoFromEnvGoal};
|
||||
use rustc::hir::{Node, TraitItemKind, ImplItemKind, ItemKind, ForeignItemKind};
|
||||
use rustc::ty::subst::{Subst, Substs};
|
||||
|
||||
debug!("environment(def_id = {:?})", def_id);
|
||||
|
||||
// The environment of an impl Trait type is its defining function's environment.
|
||||
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
|
||||
return environment(tcx, parent);
|
||||
}
|
||||
|
||||
let bound_vars = Substs::bound_vars_for_item(tcx, def_id);
|
||||
|
||||
// Compute the bounds on `Self` and the type parameters.
|
||||
let ty::InstantiatedPredicates { predicates } = tcx.predicates_of(def_id)
|
||||
.instantiate_identity(tcx);
|
||||
|
||||
let clauses = predicates.into_iter()
|
||||
.map(|predicate| predicate.lower())
|
||||
.map(|predicate| predicate.subst(tcx, bound_vars))
|
||||
.map(|domain_goal| domain_goal.map_bound(|bound| bound.into_from_env_goal()))
|
||||
.map(|domain_goal| domain_goal.map_bound(|bound| bound.into_program_clause()))
|
||||
|
||||
@ -255,20 +253,18 @@ crate fn environment<'a, 'tcx>(
|
||||
// are well-formed.
|
||||
if is_impl {
|
||||
let trait_ref = tcx.impl_trait_ref(def_id)
|
||||
.expect("not an impl")
|
||||
.subst(tcx, bound_vars);
|
||||
.expect("not an impl");
|
||||
|
||||
input_tys.extend(
|
||||
trait_ref.substs.types().flat_map(|ty| ty.walk())
|
||||
trait_ref.input_types().flat_map(|ty| ty.walk())
|
||||
);
|
||||
}
|
||||
|
||||
// In an fn, we assume that the arguments and all their constituents are
|
||||
// well-formed.
|
||||
if is_fn {
|
||||
// `skip_binder` because we move region parameters to the root binder,
|
||||
// restored in the return type of this query
|
||||
let fn_sig = tcx.fn_sig(def_id).skip_binder().subst(tcx, bound_vars);
|
||||
let fn_sig = tcx.fn_sig(def_id);
|
||||
let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
|
||||
|
||||
input_tys.extend(
|
||||
fn_sig.inputs().iter().flat_map(|ty| ty.walk())
|
||||
@ -277,17 +273,14 @@ crate fn environment<'a, 'tcx>(
|
||||
|
||||
let clauses = clauses.chain(
|
||||
input_tys.into_iter()
|
||||
// Filter out type parameters
|
||||
.filter(|ty| match ty.sty {
|
||||
ty::Bound(..) => false,
|
||||
_ => true,
|
||||
})
|
||||
.map(|ty| DomainGoal::FromEnv(FromEnv::Ty(ty)))
|
||||
.map(|domain_goal| domain_goal.into_program_clause())
|
||||
.map(Clause::Implies)
|
||||
);
|
||||
|
||||
ty::Binder::bind(Environment {
|
||||
debug!("environment: clauses = {:?}", clauses);
|
||||
|
||||
Environment {
|
||||
clauses: tcx.mk_clauses(clauses),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -626,7 +626,7 @@ impl<'a, 'tcx> ClauseDumper<'a, 'tcx> {
|
||||
|
||||
if attr.check_name("rustc_dump_env_program_clauses") {
|
||||
let environment = self.tcx.environment(def_id);
|
||||
clauses = Some(self.tcx.program_clauses_for_env(*environment.skip_binder()));
|
||||
clauses = Some(self.tcx.program_clauses_for_env(environment));
|
||||
}
|
||||
|
||||
if let Some(clauses) = clauses {
|
||||
|
Loading…
Reference in New Issue
Block a user