From ec7362442cb16902aec489b4536a81573ab4a35f Mon Sep 17 00:00:00 2001 From: scalexm Date: Fri, 23 Nov 2018 21:03:27 +0100 Subject: [PATCH] Return an instantiated environment instead of a generic one --- src/librustc/ty/query/mod.rs | 2 +- .../chalk_context/program_clauses.rs | 23 +++++++++----- src/librustc_traits/lowering/environment.rs | 31 +++++++------------ src/librustc_traits/lowering/mod.rs | 2 +- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 023a3b049501..1c92f6bc0916 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -684,7 +684,7 @@ define_queries! { <'tcx> ) -> Clauses<'tcx>, // Get the chalk-style environment of the given item. - [] fn environment: Environment(DefId) -> ty::Binder>, + [] fn environment: Environment(DefId) -> traits::Environment<'tcx>, }, Linking { diff --git a/src/librustc_traits/chalk_context/program_clauses.rs b/src/librustc_traits/chalk_context/program_clauses.rs index b685266947b7..2b4970124e3d 100644 --- a/src/librustc_traits/chalk_context/program_clauses.rs +++ b/src/librustc_traits/chalk_context/program_clauses.rs @@ -256,6 +256,8 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> { ) -> Vec> { 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 } } diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 0a474b5e7ef1..e21428acf63c 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -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> { 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), - }) + } } diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs index 28455a1d807a..51d2894cbf45 100644 --- a/src/librustc_traits/lowering/mod.rs +++ b/src/librustc_traits/lowering/mod.rs @@ -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 {