diff --git a/src/Cargo.lock b/src/Cargo.lock index 6a9488226b1bd..2719587f20e8a 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -270,7 +270,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "chalk-engine" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1898,7 +1898,7 @@ dependencies = [ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", "fmt_macros 0.0.0", "graphviz 0.0.0", @@ -2434,7 +2434,7 @@ name = "rustc_traits" version = "0.0.0" dependencies = [ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "graphviz 0.0.0", "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", "rustc 0.0.0", @@ -3195,7 +3195,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum cargo_metadata 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2d6809b327f87369e6f3651efd2c5a96c49847a3ed2559477ecba79014751ee1" "checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16" "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3" -"checksum chalk-engine 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25ce2f28f55ed544a2a3756b7acf41dd7d6f27acffb2086439950925506af7d0" +"checksum chalk-engine 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6749eb72e7d4355d944a99f15fbaea701b978c18c5e184a025fcde942b0c9779" "checksum chalk-macros 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "295635afd6853aa9f20baeb7f0204862440c0fe994c5a253d5f479dac41d047e" "checksum chrono 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6962c635d530328acc53ac6a955e83093fedc91c5809dfac1fa60fa470830a37" "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 6c3b52196a3a2..d0ec8640ce9ef 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -31,7 +31,7 @@ syntax_pos = { path = "../libsyntax_pos" } backtrace = "0.3.3" parking_lot = "0.6" byteorder = { version = "1.1", features = ["i128"]} -chalk-engine = { version = "0.7.0", default-features=false } +chalk-engine = { version = "0.8.0", default-features=false } rustc_fs_util = { path = "../librustc_fs_util" } smallvec = { version = "0.6.5", features = ["union"] } diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index e8c89cb3e0e7e..f51a3e71d0741 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -1370,7 +1370,7 @@ impl<'a, 'tcx> HashStable> for traits::Goal<'tcx> { fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { - use traits::Goal::*; + use traits::GoalKind::*; mem::discriminant(self).hash_stable(hcx, hasher); match self { diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 286e35c5d4e95..6e4abee32c077 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -318,31 +318,33 @@ pub enum QuantifierKind { } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] -pub enum Goal<'tcx> { - Implies(Clauses<'tcx>, &'tcx Goal<'tcx>), - And(&'tcx Goal<'tcx>, &'tcx Goal<'tcx>), - Not(&'tcx Goal<'tcx>), +pub enum GoalKind<'tcx> { + Implies(Clauses<'tcx>, Goal<'tcx>), + And(Goal<'tcx>, Goal<'tcx>), + Not(Goal<'tcx>), DomainGoal(DomainGoal<'tcx>), - Quantified(QuantifierKind, ty::Binder<&'tcx Goal<'tcx>>), + Quantified(QuantifierKind, ty::Binder>), CannotProve, } +pub type Goal<'tcx> = &'tcx GoalKind<'tcx>; + pub type Goals<'tcx> = &'tcx List>; impl<'tcx> DomainGoal<'tcx> { - pub fn into_goal(self) -> Goal<'tcx> { - Goal::DomainGoal(self) + pub fn into_goal(self) -> GoalKind<'tcx> { + GoalKind::DomainGoal(self) } } -impl<'tcx> Goal<'tcx> { +impl<'tcx> GoalKind<'tcx> { pub fn from_poly_domain_goal<'a>( domain_goal: PolyDomainGoal<'tcx>, tcx: TyCtxt<'a, 'tcx, 'tcx>, - ) -> Goal<'tcx> { + ) -> GoalKind<'tcx> { match domain_goal.no_late_bound_regions() { Some(p) => p.into_goal(), - None => Goal::Quantified( + None => GoalKind::Quantified( QuantifierKind::Universal, domain_goal.map_bound(|p| tcx.mk_goal(p.into_goal())) ), diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 22e79fc2638ab..1524f89af291d 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -469,7 +469,7 @@ impl fmt::Display for traits::QuantifierKind { impl<'tcx> fmt::Display for traits::Goal<'tcx> { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - use traits::Goal::*; + use traits::GoalKind::*; match self { Implies(hypotheses, goal) => { @@ -598,25 +598,25 @@ CloneTypeFoldableAndLiftImpls! { } EnumTypeFoldableImpl! { - impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> { - (traits::Goal::Implies)(hypotheses, goal), - (traits::Goal::And)(goal1, goal2), - (traits::Goal::Not)(goal), - (traits::Goal::DomainGoal)(domain_goal), - (traits::Goal::Quantified)(qkind, goal), - (traits::Goal::CannotProve), + impl<'tcx> TypeFoldable<'tcx> for traits::GoalKind<'tcx> { + (traits::GoalKind::Implies)(hypotheses, goal), + (traits::GoalKind::And)(goal1, goal2), + (traits::GoalKind::Not)(goal), + (traits::GoalKind::DomainGoal)(domain_goal), + (traits::GoalKind::Quantified)(qkind, goal), + (traits::GoalKind::CannotProve), } } EnumLiftImpl! { - impl<'a, 'tcx> Lift<'tcx> for traits::Goal<'a> { - type Lifted = traits::Goal<'tcx>; - (traits::Goal::Implies)(hypotheses, goal), - (traits::Goal::And)(goal1, goal2), - (traits::Goal::Not)(goal), - (traits::Goal::DomainGoal)(domain_goal), - (traits::Goal::Quantified)(kind, goal), - (traits::Goal::CannotProve), + impl<'a, 'tcx> Lift<'tcx> for traits::GoalKind<'a> { + type Lifted = traits::GoalKind<'tcx>; + (traits::GoalKind::Implies)(hypotheses, goal), + (traits::GoalKind::And)(goal1, goal2), + (traits::GoalKind::Not)(goal), + (traits::GoalKind::DomainGoal)(domain_goal), + (traits::GoalKind::Quantified)(kind, goal), + (traits::GoalKind::CannotProve), } } @@ -633,7 +633,7 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List> { } } -impl<'tcx> TypeFoldable<'tcx> for &'tcx traits::Goal<'tcx> { +impl<'tcx> TypeFoldable<'tcx> for traits::Goal<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { let v = (**self).fold_with(folder); folder.tcx().mk_goal(v) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 46ba5f5ef362d..3d4ae572d0b81 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -36,7 +36,7 @@ use mir::interpret::Allocation; use ty::subst::{CanonicalSubsts, Kind, Substs, Subst}; use ty::ReprOptions; use traits; -use traits::{Clause, Clauses, Goal, Goals}; +use traits::{Clause, Clauses, GoalKind, Goal, Goals}; use ty::{self, Ty, TypeAndMut}; use ty::{TyS, TyKind, List}; use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorSubsts, Region, Const}; @@ -143,7 +143,8 @@ pub struct CtxtInterners<'tcx> { predicates: InternedSet<'tcx, List>>, const_: InternedSet<'tcx, Const<'tcx>>, clauses: InternedSet<'tcx, List>>, - goals: InternedSet<'tcx, List>>, + goal: InternedSet<'tcx, GoalKind<'tcx>>, + goal_list: InternedSet<'tcx, List>>, } impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { @@ -159,7 +160,8 @@ impl<'gcx: 'tcx, 'tcx> CtxtInterners<'tcx> { predicates: Default::default(), const_: Default::default(), clauses: Default::default(), - goals: Default::default(), + goal: Default::default(), + goal_list: Default::default(), } } @@ -1731,9 +1733,9 @@ impl<'a, 'tcx> Lift<'tcx> for Region<'a> { } } -impl<'a, 'tcx> Lift<'tcx> for &'a Goal<'a> { - type Lifted = &'tcx Goal<'tcx>; - fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option<&'tcx Goal<'tcx>> { +impl<'a, 'tcx> Lift<'tcx> for Goal<'a> { + type Lifted = Goal<'tcx>; + fn lift_to_tcx<'b, 'gcx>(&self, tcx: TyCtxt<'b, 'gcx, 'tcx>) -> Option> { if tcx.interners.arena.in_arena(*self as *const _) { return Some(unsafe { mem::transmute(*self) }); } @@ -2304,6 +2306,12 @@ impl<'tcx> Borrow for Interned<'tcx, RegionKind> { } } +impl<'tcx: 'lcx, 'lcx> Borrow> for Interned<'tcx, GoalKind<'tcx>> { + fn borrow<'a>(&'a self) -> &'a GoalKind<'lcx> { + &self.0 + } +} + impl<'tcx: 'lcx, 'lcx> Borrow<[ExistentialPredicate<'lcx>]> for Interned<'tcx, List>> { fn borrow<'a>(&'a self) -> &'a [ExistentialPredicate<'lcx>] { @@ -2419,7 +2427,8 @@ pub fn keep_local<'tcx, T: ty::TypeFoldable<'tcx>>(x: &T) -> bool { direct_interners!('tcx, region: mk_region(|r: &RegionKind| r.keep_in_local_tcx()) -> RegionKind, - const_: mk_const(|c: &Const<'_>| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx> + const_: mk_const(|c: &Const<'_>| keep_local(&c.ty) || keep_local(&c.val)) -> Const<'tcx>, + goal: mk_goal(|c: &GoalKind<'_>| keep_local(c)) -> GoalKind<'tcx> ); macro_rules! slice_interners { @@ -2438,7 +2447,7 @@ slice_interners!( type_list: _intern_type_list(Ty), substs: _intern_substs(Kind), clauses: _intern_clauses(Clause), - goals: _intern_goals(Goal) + goal_list: _intern_goals(Goal) ); // This isn't a perfect fit: CanonicalVarInfo slices are always @@ -2818,10 +2827,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { iter.intern_with(|xs| self.intern_goals(xs)) } - pub fn mk_goal(self, goal: Goal<'tcx>) -> &'tcx Goal<'_> { - &self.intern_goals(&[goal])[0] - } - pub fn lint_hir>(self, lint: &'static Lint, hir_id: HirId, diff --git a/src/librustc/ty/flags.rs b/src/librustc/ty/flags.rs index c3d41873009a7..10a90dfc8a8cf 100644 --- a/src/librustc/ty/flags.rs +++ b/src/librustc/ty/flags.rs @@ -148,7 +148,10 @@ impl FlagComputation { self.add_projection_ty(data); } - &ty::UnnormalizedProjection(..) => bug!("only used with chalk-engine"), + &ty::UnnormalizedProjection(ref data) => { + self.add_flags(TypeFlags::HAS_PROJECTION); + self.add_projection_ty(data); + }, &ty::Opaque(_, substs) => { self.add_flags(TypeFlags::HAS_PROJECTION); diff --git a/src/librustc_traits/Cargo.toml b/src/librustc_traits/Cargo.toml index cd21ee601a7d2..16f0f11757a12 100644 --- a/src/librustc_traits/Cargo.toml +++ b/src/librustc_traits/Cargo.toml @@ -16,5 +16,5 @@ rustc = { path = "../librustc" } rustc_data_structures = { path = "../librustc_data_structures" } syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } -chalk-engine = { version = "0.7.0", default-features=false } +chalk-engine = { version = "0.8.0", default-features=false } smallvec = { version = "0.6.5", features = ["union"] } diff --git a/src/librustc_traits/chalk_context.rs b/src/librustc_traits/chalk_context.rs index 4c28df97bdf50..dea3aa4372a33 100644 --- a/src/librustc_traits/chalk_context.rs +++ b/src/librustc_traits/chalk_context.rs @@ -19,6 +19,7 @@ use rustc::traits::{ ExClauseFold, ExClauseLift, Goal, + GoalKind, ProgramClause, QuantifierKind }; @@ -92,7 +93,7 @@ impl context::Context for ChalkArenas<'tcx> { type DomainGoal = DomainGoal<'tcx>; - type BindersGoal = ty::Binder<&'tcx Goal<'tcx>>; + type BindersGoal = ty::Binder>; type Parameter = Kind<'tcx>; @@ -102,14 +103,6 @@ impl context::Context for ChalkArenas<'tcx> { type UnificationResult = InferOk<'tcx, ()>; - fn into_goal(domain_goal: DomainGoal<'tcx>) -> Goal<'tcx> { - Goal::DomainGoal(domain_goal) - } - - fn cannot_prove() -> Goal<'tcx> { - Goal::CannotProve - } - fn goal_in_environment( env: &ty::ParamEnv<'tcx>, goal: Goal<'tcx>, @@ -251,15 +244,23 @@ impl context::ContextOps> for ChalkContext<'cx, 'gcx> { impl context::InferenceTable, ChalkArenas<'tcx>> for ChalkInferenceContext<'cx, 'gcx, 'tcx> { + fn into_goal(&self, domain_goal: DomainGoal<'tcx>) -> Goal<'tcx> { + self.infcx.tcx.mk_goal(GoalKind::DomainGoal(domain_goal)) + } + + fn cannot_prove(&self) -> Goal<'tcx> { + self.infcx.tcx.mk_goal(GoalKind::CannotProve) + } + fn into_hh_goal(&mut self, goal: Goal<'tcx>) -> ChalkHhGoal<'tcx> { - match goal { - Goal::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"), - Goal::And(left, right) => HhGoal::And(*left, *right), - Goal::Not(subgoal) => HhGoal::Not(*subgoal), - Goal::DomainGoal(d) => HhGoal::DomainGoal(d), - Goal::Quantified(QuantifierKind::Universal, binder) => HhGoal::ForAll(binder), - Goal::Quantified(QuantifierKind::Existential, binder) => HhGoal::Exists(binder), - Goal::CannotProve => HhGoal::CannotProve, + match *goal { + GoalKind::Implies(..) => panic!("FIXME rust-lang-nursery/chalk#94"), + GoalKind::And(left, right) => HhGoal::And(left, right), + GoalKind::Not(subgoal) => HhGoal::Not(subgoal), + GoalKind::DomainGoal(d) => HhGoal::DomainGoal(d), + GoalKind::Quantified(QuantifierKind::Universal, binder) => HhGoal::ForAll(binder), + GoalKind::Quantified(QuantifierKind::Existential, binder) => HhGoal::Exists(binder), + GoalKind::CannotProve => HhGoal::CannotProve, } } @@ -363,21 +364,21 @@ impl context::UnificationOps, ChalkArenas<'tcx>> fn instantiate_binders_universally( &mut self, - _arg: &ty::Binder<&'tcx Goal<'tcx>>, + _arg: &ty::Binder>, ) -> Goal<'tcx> { panic!("FIXME -- universal instantiation needs sgrif's branch") } fn instantiate_binders_existentially( &mut self, - arg: &ty::Binder<&'tcx Goal<'tcx>>, + arg: &ty::Binder>, ) -> Goal<'tcx> { let (value, _map) = self.infcx.replace_late_bound_regions_with_fresh_var( DUMMY_SP, LateBoundRegionConversionTime::HigherRankedType, arg, ); - *value + value } fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box { diff --git a/src/librustc_traits/lowering.rs b/src/librustc_traits/lowering.rs index ad724babe49fb..181106d3f84bf 100644 --- a/src/librustc_traits/lowering.rs +++ b/src/librustc_traits/lowering.rs @@ -13,7 +13,14 @@ use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc::hir::map::definitions::DefPathData; use rustc::hir::{self, ImplPolarity}; use rustc::traits::{ - Clause, Clauses, DomainGoal, FromEnv, Goal, PolyDomainGoal, ProgramClause, WellFormed, + Clause, + Clauses, + DomainGoal, + FromEnv, + GoalKind, + PolyDomainGoal, + ProgramClause, + WellFormed, WhereClause, }; use rustc::ty::query::Providers; @@ -249,7 +256,7 @@ fn program_clauses_for_trait<'a, 'tcx>( let impl_trait: DomainGoal = trait_pred.lower(); // `FromEnv(Self: Trait)` - let from_env_goal = impl_trait.into_from_env_goal().into_goal(); + let from_env_goal = tcx.mk_goal(impl_trait.into_from_env_goal().into_goal()); let hypotheses = tcx.intern_goals(&[from_env_goal]); // `Implemented(Self: Trait) :- FromEnv(Self: Trait)` @@ -308,7 +315,7 @@ fn program_clauses_for_trait<'a, 'tcx>( let wf_clause = ProgramClause { goal: DomainGoal::WellFormed(WellFormed::Trait(trait_pred)), hypotheses: tcx.mk_goals( - wf_conditions.map(|wc| Goal::from_poly_domain_goal(wc, tcx)), + wf_conditions.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))), ), }; let wf_clause = iter::once(Clause::ForAll(ty::Binder::dummy(wf_clause))); @@ -352,10 +359,10 @@ fn program_clauses_for_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId hypotheses: tcx.mk_goals( where_clauses .into_iter() - .map(|wc| Goal::from_poly_domain_goal(wc, tcx)), + .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))), ), }; - tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))]) + tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause)))) } pub fn program_clauses_for_type_def<'a, 'tcx>( @@ -388,7 +395,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>( where_clauses .iter() .cloned() - .map(|wc| Goal::from_poly_domain_goal(wc, tcx)), + .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))), ), }; @@ -404,7 +411,7 @@ pub fn program_clauses_for_type_def<'a, 'tcx>( // ``` // `FromEnv(Ty<...>)` - let from_env_goal = DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal(); + let from_env_goal = tcx.mk_goal(DomainGoal::FromEnv(FromEnv::Ty(ty)).into_goal()); let hypotheses = tcx.intern_goals(&[from_env_goal]); // For each where clause `WC`: @@ -423,10 +430,86 @@ pub fn program_clauses_for_type_def<'a, 'tcx>( } pub fn program_clauses_for_associated_type_def<'a, 'tcx>( - _tcx: TyCtxt<'a, 'tcx, 'tcx>, - _item_id: DefId, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + item_id: DefId, ) -> Clauses<'tcx> { - unimplemented!() + // Rule ProjectionEq-Skolemize + // + // ``` + // trait Trait { + // type AssocType; + // } + // ``` + // + // `ProjectionEq` can succeed by skolemizing, see "associated type" + // chapter for more: + // ``` + // forall { + // ProjectionEq( + // >::AssocType = + // (Trait::AssocType) + // ) + // } + // ``` + + let item = tcx.associated_item(item_id); + debug_assert_eq!(item.kind, ty::AssociatedKind::Type); + let trait_id = match item.container { + ty::AssociatedItemContainer::TraitContainer(trait_id) => trait_id, + _ => bug!("not an trait container"), + }; + let trait_ref = ty::TraitRef::identity(tcx, trait_id); + + let projection_ty = ty::ProjectionTy::from_ref_and_name(tcx, trait_ref, item.ident); + let placeholder_ty = tcx.mk_ty(ty::UnnormalizedProjection(projection_ty)); + let projection_eq = WhereClause::ProjectionEq(ty::ProjectionPredicate { + projection_ty, + ty: placeholder_ty, + }); + + let projection_eq_clause = ProgramClause { + goal: DomainGoal::Holds(projection_eq), + hypotheses: &ty::List::empty(), + }; + + // Rule WellFormed-AssocTy + // ``` + // forall { + // WellFormed((Trait::AssocType)) + // :- Implemented(Self: Trait) + // } + // ``` + + let trait_predicate = ty::TraitPredicate { trait_ref }; + let hypothesis = tcx.mk_goal( + DomainGoal::Holds(WhereClause::Implemented(trait_predicate)).into_goal() + ); + let wf_clause = ProgramClause { + goal: DomainGoal::WellFormed(WellFormed::Ty(placeholder_ty)), + hypotheses: tcx.mk_goals(iter::once(hypothesis)), + }; + + // Rule Implied-Trait-From-AssocTy + // ``` + // forall { + // FromEnv(Self: Trait) + // :- FromEnv((Trait::AssocType)) + // } + // ``` + + let hypothesis = tcx.mk_goal( + DomainGoal::FromEnv(FromEnv::Ty(placeholder_ty)).into_goal() + ); + let from_env_clause = ProgramClause { + goal: DomainGoal::FromEnv(FromEnv::Trait(trait_predicate)), + hypotheses: tcx.mk_goals(iter::once(hypothesis)), + }; + + let clauses = iter::once(projection_eq_clause) + .chain(iter::once(wf_clause)) + .chain(iter::once(from_env_clause)); + let clauses = clauses.map(|clause| Clause::ForAll(ty::Binder::dummy(clause))); + tcx.mk_clauses(clauses) } pub fn program_clauses_for_associated_type_value<'a, 'tcx>( @@ -435,10 +518,11 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>( ) -> Clauses<'tcx> { // Rule Normalize-From-Impl (see rustc guide) // - // ```impl Trait for A0 - // { + // ``` + // impl Trait for A0 { // type AssocType = T; - // }``` + // } + // ``` // // FIXME: For the moment, we don't account for where clauses written on the associated // ty definition (i.e. in the trait def, as in `type AssocType where T: Sized`). @@ -482,10 +566,10 @@ pub fn program_clauses_for_associated_type_value<'a, 'tcx>( hypotheses: tcx.mk_goals( hypotheses .into_iter() - .map(|wc| Goal::from_poly_domain_goal(wc, tcx)), + .map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))), ), }; - tcx.intern_clauses(&[Clause::ForAll(ty::Binder::dummy(clause))]) + tcx.mk_clauses(iter::once(Clause::ForAll(ty::Binder::dummy(clause)))) } pub fn dump_program_clauses<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) { diff --git a/src/test/ui/chalkify/lower_trait.rs b/src/test/ui/chalkify/lower_trait.rs index c5ba5beeca7a5..ba7d4ff0d9bf5 100644 --- a/src/test/ui/chalkify/lower_trait.rs +++ b/src/test/ui/chalkify/lower_trait.rs @@ -10,11 +10,12 @@ #![feature(rustc_attrs)] +trait Bar { } + #[rustc_dump_program_clauses] //~ ERROR program clause dump -trait Foo { - fn s(_: S) -> S; - fn t(_: T) -> T; - fn u(_: U) -> U; +trait Foo { + #[rustc_dump_program_clauses] //~ ERROR program clause dump + type Assoc: Bar + ?Sized; } fn main() { diff --git a/src/test/ui/chalkify/lower_trait.stderr b/src/test/ui/chalkify/lower_trait.stderr index c4e768415d60b..dc2375277e734 100644 --- a/src/test/ui/chalkify/lower_trait.stderr +++ b/src/test/ui/chalkify/lower_trait.stderr @@ -1,14 +1,23 @@ error: program clause dump - --> $DIR/lower_trait.rs:13:1 + --> $DIR/lower_trait.rs:15:1 | LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo). - = note: FromEnv(T: std::marker::Sized) :- FromEnv(Self: Foo). - = note: FromEnv(U: std::marker::Sized) :- FromEnv(Self: Foo). - = note: Implemented(Self: Foo) :- FromEnv(Self: Foo). - = note: WellFormed(Self: Foo) :- Implemented(Self: Foo), WellFormed(S: std::marker::Sized), WellFormed(T: std::marker::Sized), WellFormed(U: std::marker::Sized). + = note: FromEnv(>::Assoc: Bar) :- FromEnv(Self: Foo). + = note: FromEnv(S: std::marker::Sized) :- FromEnv(Self: Foo). + = note: Implemented(Self: Foo) :- FromEnv(Self: Foo). + = note: WellFormed(Self: Foo) :- Implemented(Self: Foo), WellFormed(S: std::marker::Sized), WellFormed(>::Assoc: Bar). -error: aborting due to previous error +error: program clause dump + --> $DIR/lower_trait.rs:17:5 + | +LL | #[rustc_dump_program_clauses] //~ ERROR program clause dump + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: FromEnv(Self: Foo) :- FromEnv(Unnormalized(>::Assoc)). + = note: ProjectionEq(>::Assoc == Unnormalized(>::Assoc)). + = note: WellFormed(Unnormalized(>::Assoc)) :- Implemented(Self: Foo). + +error: aborting due to 2 previous errors