From d66452c3e5dfad901099493e8b86f5643d084a32 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Tue, 4 Aug 2020 18:35:37 -0400 Subject: [PATCH 1/5] Upgrade chalk to 0.21 --- Cargo.lock | 61 ++++++++-- compiler/rustc_middle/Cargo.toml | 2 +- compiler/rustc_middle/src/traits/chalk.rs | 15 +++ compiler/rustc_traits/Cargo.toml | 5 +- compiler/rustc_traits/src/chalk/db.rs | 118 +++++++------------- compiler/rustc_traits/src/chalk/lowering.rs | 78 +++++++++---- compiler/rustc_traits/src/chalk/mod.rs | 11 +- src/test/ui/chalkify/type_inference.rs | 2 +- src/test/ui/chalkify/type_inference.stderr | 8 +- src/test/ui/chalkify/type_wf.rs | 2 +- src/test/ui/chalkify/type_wf.stderr | 8 +- 11 files changed, 190 insertions(+), 120 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f94d95d2dc8..d4e718cb603 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,9 +427,9 @@ dependencies = [ [[package]] name = "chalk-derive" -version = "0.14.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d463e01905d607e181de72e8608721d3269f29176c9a14ce037011316ae7131d" +checksum = "c1df0dbb57d74b4acd20f20fa66ab2acd09776b79eaeb9d8f947b2f3e01c40bf" dependencies = [ "proc-macro2", "quote", @@ -439,21 +439,22 @@ dependencies = [ [[package]] name = "chalk-engine" -version = "0.14.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efaf428f5398d36284f79690cf988762b7c091249f50a6c11db613a46c057000" +checksum = "fb7c65a13f32f02aba8f1d9a37f206af615f77ac564624b81a4c593c6c1735b9" dependencies = [ "chalk-derive", "chalk-ir", + "chalk-solve", "rustc-hash", "tracing", ] [[package]] name = "chalk-ir" -version = "0.14.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd3fdc1e9f68498ffe80f4a23b0b95f1ca6fb21d5a4c9b0c085fab3ca712bdbe" +checksum = "44361a25dbdb1dc428f56ad7a3c21ba9ca12f3225c26a47919ff6fcb10a583d4" dependencies = [ "chalk-derive", "lazy_static", @@ -461,18 +462,19 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.14.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b9fd4102807b7ebe8fb034fa0f488c5656e1966d3261b558b81a08d519cdb29" +checksum = "a886da37a0dc457057d86f78f026f7a09c6d8088aa13f4f4127fdb8dc80119a3" dependencies = [ "chalk-derive", - "chalk-engine", "chalk-ir", "ena", "itertools 0.9.0", "petgraph", "rustc-hash", "tracing", + "tracing-subscriber", + "tracing-tree", ] [[package]] @@ -4038,6 +4040,7 @@ dependencies = [ name = "rustc_traits" version = "0.0.0" dependencies = [ + "chalk-engine", "chalk-ir", "chalk-solve", "rustc_ast", @@ -4996,6 +4999,27 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tracing-log" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e0f8c7178e13481ff6765bd169b33e8d554c5d2bbede5e32c356194be02b9b9" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6ccba2f8f16e0ed268fc765d9b7ff22e965e7185d32f8f1ec8294fe17d86e79" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.2.11" @@ -5003,14 +5027,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abd165311cc4d7a555ad11cc77a37756df836182db0d81aac908c8184c584f40" dependencies = [ "ansi_term 0.12.1", + "chrono", "lazy_static", "matchers", "parking_lot 0.11.0", "regex", + "serde", + "serde_json", "sharded-slab", "smallvec 1.4.2", "thread_local", "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "tracing-tree" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1a3dc4774db3a6b2d66a4f8d8de670e874ec3ed55615860c994927419b32c5f" +dependencies = [ + "ansi_term 0.12.1", + "atty", + "chrono", + "termcolor", + "tracing", + "tracing-subscriber", ] [[package]] diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 5a82cbf2997..302a907538c 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -27,7 +27,7 @@ rustc_serialize = { path = "../rustc_serialize" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } byteorder = { version = "1.3" } -chalk-ir = "0.14.0" +chalk-ir = "0.21.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } measureme = "0.7.1" rustc_session = { path = "../rustc_session" } diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs index 405af8cb240..d03c32533f8 100644 --- a/compiler/rustc_middle/src/traits/chalk.rs +++ b/compiler/rustc_middle/src/traits/chalk.rs @@ -75,6 +75,7 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { type InternedQuantifiedWhereClauses = Vec>; type InternedVariableKinds = Vec>; type InternedCanonicalVarKinds = Vec>; + type InternedConstraints = Vec>>; type DefId = DefId; type InternedAdtId = &'tcx AdtDef; type Identifier = (); @@ -321,6 +322,20 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { ) -> &'a [chalk_ir::CanonicalVarKind] { canonical_var_kinds } + + fn intern_constraints( + &self, + data: impl IntoIterator>, E>>, + ) -> Result { + data.into_iter().collect::, _>>() + } + + fn constraints_data<'a>( + &self, + constraints: &'a Self::InternedConstraints, + ) -> &'a [chalk_ir::InEnvironment>] { + constraints + } } impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> { diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 2d63fc51220..3571ff17f31 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -12,8 +12,9 @@ rustc_hir = { path = "../rustc_hir" } rustc_index = { path = "../rustc_index" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } -chalk-ir = "0.14.0" -chalk-solve = "0.14.0" +chalk-ir = "0.21.0" +chalk-solve = "0.21.0" +chalk-engine = "0.21.0" smallvec = { version = "1.0", features = ["union", "may_dangle"] } rustc_infer = { path = "../rustc_infer" } rustc_trait_selection = { path = "../rustc_trait_selection" } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index c2f2469a140..877886ad601 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -11,6 +11,7 @@ use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt}; use rustc_hir::def_id::DefId; +use rustc_hir::Unsafety; use rustc_span::symbol::sym; @@ -145,10 +146,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)) .collect(); - let fields = match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => { - let variant = adt_def.non_enum_variant(); - variant + let variants: Vec<_> = adt_def + .variants + .iter() + .map(|variant| chalk_solve::rust_ir::AdtVariantDatum { + fields: variant .fields .iter() .map(|field| { @@ -157,26 +159,40 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .subst(self.tcx, bound_vars) .lower_into(&self.interner) }) - .collect() - } - // FIXME(chalk): handle enums; force_impl_for requires this - ty::AdtKind::Enum => vec![], - }; + .collect(), + }) + .collect(); let struct_datum = Arc::new(chalk_solve::rust_ir::AdtDatum { id: adt_id, binders: chalk_ir::Binders::new( binders, - chalk_solve::rust_ir::AdtDatumBound { fields, where_clauses }, + chalk_solve::rust_ir::AdtDatumBound { variants, where_clauses }, ), flags: chalk_solve::rust_ir::AdtFlags { upstream: !adt_def.did.is_local(), fundamental: adt_def.is_fundamental(), phantom_data: adt_def.is_phantom_data(), }, + kind: match adt_def.adt_kind() { + ty::AdtKind::Struct => chalk_solve::rust_ir::AdtKind::Struct, + ty::AdtKind::Union => chalk_solve::rust_ir::AdtKind::Union, + ty::AdtKind::Enum => chalk_solve::rust_ir::AdtKind::Enum, + }, }); struct_datum } + fn adt_repr( + &self, + adt_id: chalk_ir::AdtId>, + ) -> chalk_solve::rust_ir::AdtRepr { + let adt_def = adt_id.0; + chalk_solve::rust_ir::AdtRepr { + repr_c: adt_def.repr.c(), + repr_packed: adt_def.repr.packed(), + } + } + fn fn_def_datum( &self, fn_def_id: chalk_ir::FnDefId>, @@ -218,6 +234,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t Arc::new(chalk_solve::rust_ir::FnDefDatum { id: fn_def_id, abi: sig.abi(), + safety: match sig.unsafety() { + Unsafety::Normal => chalk_ir::Safety::Safe, + Unsafety::Unsafe => chalk_ir::Safety::Unsafe, + }, + variadic: sig.c_variadic(), binders: chalk_ir::Binders::new(binders, bound), }) } @@ -256,6 +277,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t &self, trait_id: chalk_ir::TraitId>, parameters: &[chalk_ir::GenericArg>], + _binders: &chalk_ir::CanonicalVarKinds>, ) -> Vec>> { let def_id = trait_id.0; @@ -355,69 +377,15 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); let value = chalk_solve::rust_ir::OpaqueTyDatumBound { - bounds: chalk_ir::Binders::new(binders, where_clauses), + bounds: chalk_ir::Binders::new(binders.clone(), vec![]), + where_clauses: chalk_ir::Binders::new(binders, where_clauses), }; Arc::new(chalk_solve::rust_ir::OpaqueTyDatum { opaque_ty_id, - bound: chalk_ir::Binders::new(chalk_ir::VariableKinds::new(&self.interner), value), + bound: chalk_ir::Binders::new(chalk_ir::VariableKinds::empty(&self.interner), value), }) } - /// Since Chalk can't handle all Rust types currently, we have to handle - /// some specially for now. Over time, these `Some` returns will change to - /// `None` and eventually this function will be removed. - fn force_impl_for( - &self, - well_known: chalk_solve::rust_ir::WellKnownTrait, - ty: &chalk_ir::TyData>, - ) -> Option { - use chalk_ir::TyData::*; - match well_known { - chalk_solve::rust_ir::WellKnownTrait::Sized => match ty { - Apply(apply) => match apply.name { - chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => None, - ty::AdtKind::Enum => { - let constraint = self.tcx.adt_sized_constraint(adt_def.did); - if !constraint.0.is_empty() { unimplemented!() } else { Some(true) } - } - }, - _ => None, - }, - Dyn(_) - | Alias(_) - | Placeholder(_) - | Function(_) - | InferenceVar(_, _) - | BoundVar(_) => None, - }, - chalk_solve::rust_ir::WellKnownTrait::Copy - | chalk_solve::rust_ir::WellKnownTrait::Clone => match ty { - Apply(apply) => match apply.name { - chalk_ir::TypeName::Adt(chalk_ir::AdtId(adt_def)) => match adt_def.adt_kind() { - ty::AdtKind::Struct | ty::AdtKind::Union => None, - ty::AdtKind::Enum => { - let constraint = self.tcx.adt_sized_constraint(adt_def.did); - if !constraint.0.is_empty() { unimplemented!() } else { Some(true) } - } - }, - _ => None, - }, - Dyn(_) - | Alias(_) - | Placeholder(_) - | Function(_) - | InferenceVar(_, _) - | BoundVar(_) => None, - }, - chalk_solve::rust_ir::WellKnownTrait::Drop => None, - chalk_solve::rust_ir::WellKnownTrait::Fn => None, - chalk_solve::rust_ir::WellKnownTrait::FnMut => None, - chalk_solve::rust_ir::WellKnownTrait::FnOnce => None, - chalk_solve::rust_ir::WellKnownTrait::Unsize => None, - } - } - fn program_clauses_for_env( &self, environment: &chalk_ir::Environment>, @@ -460,7 +428,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t _closure_id: chalk_ir::ClosureId>, substs: &chalk_ir::Substitution>, ) -> chalk_solve::rust_ir::ClosureKind { - let kind = &substs.parameters(&self.interner)[substs.len(&self.interner) - 3]; + let kind = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 3]; match kind.assert_ty_ref(&self.interner).data(&self.interner) { chalk_ir::TyData::Apply(apply) => match apply.name { chalk_ir::TypeName::Scalar(scalar) => match scalar { @@ -484,10 +452,10 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t substs: &chalk_ir::Substitution>, ) -> chalk_ir::Binders>> { - let sig = &substs.parameters(&self.interner)[substs.len(&self.interner) - 2]; + let sig = &substs.as_slice(&self.interner)[substs.len(&self.interner) - 2]; match sig.assert_ty_ref(&self.interner).data(&self.interner) { chalk_ir::TyData::Function(f) => { - let substitution = f.substitution.parameters(&self.interner); + let substitution = f.substitution.as_slice(&self.interner); let return_type = substitution.last().unwrap().assert_ty_ref(&self.interner).clone(); // Closure arguments are tupled @@ -506,7 +474,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }; chalk_ir::Binders::new( - chalk_ir::VariableKinds::from( + chalk_ir::VariableKinds::from_iter( &self.interner, (0..f.num_binders).map(|_| chalk_ir::VariableKind::Lifetime), ), @@ -523,7 +491,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t substs: &chalk_ir::Substitution>, ) -> chalk_ir::Binders>> { let inputs_and_output = self.closure_inputs_and_output(_closure_id, substs); - let tuple = substs.parameters(&self.interner).last().unwrap().assert_ty_ref(&self.interner); + let tuple = substs.as_slice(&self.interner).last().unwrap().assert_ty_ref(&self.interner); inputs_and_output.map_ref(|_| tuple.clone()) } @@ -532,8 +500,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t _closure_id: chalk_ir::ClosureId>, substs: &chalk_ir::Substitution>, ) -> chalk_ir::Substitution> { - let substitution = &substs.parameters(&self.interner)[0..substs.len(&self.interner) - 3]; - chalk_ir::Substitution::from(&self.interner, substitution) + let substitution = &substs.as_slice(&self.interner)[0..substs.len(&self.interner) - 3]; + chalk_ir::Substitution::from_iter(&self.interner, substitution) } } @@ -573,7 +541,7 @@ fn binders_for<'tcx>( interner: &RustInterner<'tcx>, bound_vars: SubstsRef<'tcx>, ) -> chalk_ir::VariableKinds> { - chalk_ir::VariableKinds::from( + chalk_ir::VariableKinds::from_iter( interner, bound_vars.iter().map(|arg| match arg.unpack() { ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::VariableKind::Lifetime, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 779540ecd24..b5332383988 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -56,7 +56,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution>> for Subst self, interner: &RustInterner<'tcx>, ) -> chalk_ir::Substitution> { - chalk_ir::Substitution::from(interner, self.iter().map(|s| s.lower_into(interner))) + chalk_ir::Substitution::from_iter(interner, self.iter().map(|s| s.lower_into(interner))) } } @@ -94,8 +94,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment LowerInto<'tcx, chalk_ir::InEnvironment { + let predicate = ty::Binder::bind(predicate); + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, &predicate); + + Some( + chalk_ir::ProgramClauseData(chalk_ir::Binders::new( + binders, + chalk_ir::ProgramClauseImplication { + consequence: chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::TypeOutlives( + chalk_ir::TypeOutlives { + ty: predicate.0.lower_into(interner), + lifetime: predicate.1.lower_into(interner), + }, + ), + ), + conditions: chalk_ir::Goals::empty(interner), + priority: chalk_ir::ClausePriority::High, + constraints: chalk_ir::Constraints::empty(interner), }, )) .intern(interner), ) } - // FIXME(chalk): need to add TypeOutlives - ty::PredicateAtom::TypeOutlives(_) => None, ty::PredicateAtom::Projection(predicate) => { let predicate = ty::Binder::bind(predicate); let (predicate, binders, _named_regions) = @@ -141,8 +166,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment LowerInto<'tcx, chalk_ir::InEnvironment Some( chalk_ir::ProgramClauseData(chalk_ir::Binders::new( - chalk_ir::VariableKinds::new(interner), + chalk_ir::VariableKinds::empty(interner), chalk_ir::ProgramClauseImplication { consequence: chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty( ty.lower_into(interner).shifted_in(interner), )), - conditions: chalk_ir::Goals::new(interner), + conditions: chalk_ir::Goals::empty(interner), priority: chalk_ir::ClausePriority::High, + constraints: chalk_ir::Constraints::empty(interner), }, )) .intern(interner), @@ -176,7 +203,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment> = self.goal.lower_into(&interner); chalk_ir::InEnvironment { environment: chalk_ir::Environment { - clauses: chalk_ir::ProgramClauses::from(&interner, clauses), + clauses: chalk_ir::ProgramClauses::from_iter(&interner, clauses), }, goal: goal.intern(&interner), } @@ -211,7 +238,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi } // FIXME(chalk): TypeOutlives ty::PredicateAtom::TypeOutlives(_predicate) => { - chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)) + chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } ty::PredicateAtom::Projection(predicate) => { ty::Binder::bind(predicate).lower_into(interner) @@ -221,7 +248,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi // FIXME(chalk): In Chalk, a placeholder is WellFormed if it // `FromEnv`. However, when we "lower" Params, we don't update // the environment. - ty::Placeholder(..) => chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)), + ty::Placeholder(..) => { + chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) + } _ => { let (ty, binders, _named_regions) = @@ -241,7 +270,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi }, // FIXME(chalk): handle well formed consts GenericArgKind::Const(..) => { - chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)) + chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } GenericArgKind::Lifetime(lt) => bug!("unexpect well formed predicate: {:?}", lt), }, @@ -258,7 +287,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi | ty::PredicateAtom::Subtype(..) | ty::PredicateAtom::ConstEvaluatable(..) | ty::PredicateAtom::ConstEquate(..) => { - chalk_ir::GoalData::All(chalk_ir::Goals::new(interner)) + chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } } } @@ -381,7 +410,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { }; apply( chalk_ir::TypeName::Array, - chalk_ir::Substitution::from( + chalk_ir::Substitution::from_iter( interner, &[ chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner), @@ -415,7 +444,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { }; apply( name, - chalk_ir::Substitution::from( + chalk_ir::Substitution::from_iter( interner, &[ chalk_ir::GenericArgData::Lifetime(region.lower_into(interner)) @@ -432,14 +461,20 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { FnPtr(sig) => { let (inputs_and_outputs, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &sig.inputs_and_output()); - TyData::Function(chalk_ir::Fn { + TyData::Function(chalk_ir::FnPointer { num_binders: binders.len(interner), - substitution: chalk_ir::Substitution::from( + substitution: chalk_ir::Substitution::from_iter( interner, inputs_and_outputs.iter().map(|ty| { chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner) }), ), + abi: sig.abi(), + safety: match sig.unsafety() { + rustc_hir::Unsafety::Normal => chalk_ir::Safety::Safe, + rustc_hir::Unsafety::Unsafe => chalk_ir::Safety::Unsafe, + }, + variadic: sig.c_variadic(), }) .intern(interner) } @@ -604,7 +639,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders { chalk_ir::Binders::new( - chalk_ir::VariableKinds::new(interner), + chalk_ir::VariableKinds::empty(interner), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(def_id), substitution: substs.lower_into(interner), @@ -613,14 +648,14 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders unimplemented!(), ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( - chalk_ir::VariableKinds::new(interner), + chalk_ir::VariableKinds::empty(interner), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(def_id), substitution: chalk_ir::Substitution::empty(interner), }), ), }); - let value = chalk_ir::QuantifiedWhereClauses::from(interner, where_clauses); + let value = chalk_ir::QuantifiedWhereClauses::from_iter(interner, where_clauses); chalk_ir::Binders::new(binders, value) } } @@ -662,7 +697,8 @@ crate fn collect_bound_vars<'a, 'tcx, T: TypeFoldable<'tcx>>( .or_else(|| bug!("Skipped bound var index: ty={:?}, parameters={:?}", ty, parameters)); }); - let binders = chalk_ir::VariableKinds::from(interner, parameters.into_iter().map(|(_, v)| v)); + let binders = + chalk_ir::VariableKinds::from_iter(interner, parameters.into_iter().map(|(_, v)| v)); (new_ty, binders, named_parameters) } diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index f18b4ca65f6..52648477f02 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -49,7 +49,7 @@ crate fn evaluate_goal<'tcx>( chalk_ir::InEnvironment>>, > = chalk_ir::UCanonical { canonical: chalk_ir::Canonical { - binders: chalk_ir::CanonicalVarKinds::from( + binders: chalk_ir::CanonicalVarKinds::from_iter( &interner, obligation.variables.iter().map(|v| match v.kind { CanonicalVarKind::PlaceholderTy(_ty) => unimplemented!(), @@ -81,11 +81,10 @@ crate fn evaluate_goal<'tcx>( universes: max_universe + 1, }; - let solver_choice = chalk_solve::SolverChoice::SLG { max_size: 32, expected_answers: None }; - let mut solver = solver_choice.into_solver::>(); - + use chalk_solve::Solver; + let mut solver = chalk_engine::solve::SLGSolver::new(32, None); let db = ChalkRustIrDatabase { tcx, interner }; - let solution = solver.solve(&db, &_lowered_goal); + let solution = chalk_solve::logging::with_tracing_logs(|| solver.solve(&db, &_lowered_goal)); // Ideally, the code to convert *back* to rustc types would live close to // the code to convert *from* rustc types. Right now though, we don't @@ -94,7 +93,7 @@ crate fn evaluate_goal<'tcx>( // `Ambig(Definite)`. This really isn't right. let make_solution = |_subst: chalk_ir::Substitution<_>| { let mut var_values: IndexVec> = IndexVec::new(); - _subst.parameters(&interner).iter().for_each(|p| { + _subst.as_slice(&interner).iter().for_each(|p| { // FIXME(chalk): we should move this elsewhere, since this is // essentially inverse of lowering a `GenericArg`. let _data = p.data(&interner); diff --git a/src/test/ui/chalkify/type_inference.rs b/src/test/ui/chalkify/type_inference.rs index 2b62bf18a71..369777a7904 100644 --- a/src/test/ui/chalkify/type_inference.rs +++ b/src/test/ui/chalkify/type_inference.rs @@ -24,5 +24,5 @@ fn main() { // Here we have two solutions so we get back the behavior of the old-style // trait solver. - only_bar(x); //~ ERROR the trait bound `f64: Bar` is not satisfied + only_bar(x); //~ ERROR the trait bound `{float}: Bar` is not satisfied } diff --git a/src/test/ui/chalkify/type_inference.stderr b/src/test/ui/chalkify/type_inference.stderr index 5cfb968404d..fb8ccbfc660 100644 --- a/src/test/ui/chalkify/type_inference.stderr +++ b/src/test/ui/chalkify/type_inference.stderr @@ -1,11 +1,15 @@ -error[E0277]: the trait bound `f64: Bar` is not satisfied +error[E0277]: the trait bound `{float}: Bar` is not satisfied --> $DIR/type_inference.rs:27:5 | LL | fn only_bar(_x: T) { } | --- required by this bound in `only_bar` ... LL | only_bar(x); - | ^^^^^^^^ the trait `Bar` is not implemented for `f64` + | ^^^^^^^^ the trait `Bar` is not implemented for `{float}` + | + = help: the following implementations were found: + + error: aborting due to previous error diff --git a/src/test/ui/chalkify/type_wf.rs b/src/test/ui/chalkify/type_wf.rs index 7c469d99c57..dd83a03fdf6 100644 --- a/src/test/ui/chalkify/type_wf.rs +++ b/src/test/ui/chalkify/type_wf.rs @@ -15,7 +15,7 @@ fn main() { x: 5, }; - let s = S { //~ ERROR the trait bound `f64: Foo` is not satisfied + let s = S { //~ ERROR the trait bound `{float}: Foo` is not satisfied x: 5.0, }; diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr index ab585a6ed21..71009f1e97d 100644 --- a/src/test/ui/chalkify/type_wf.stderr +++ b/src/test/ui/chalkify/type_wf.stderr @@ -1,11 +1,15 @@ -error[E0277]: the trait bound `f64: Foo` is not satisfied +error[E0277]: the trait bound `{float}: Foo` is not satisfied --> $DIR/type_wf.rs:18:13 | LL | struct S { | ---------------- required by `S` ... LL | let s = S { - | ^ the trait `Foo` is not implemented for `f64` + | ^ the trait `Foo` is not implemented for `{float}` + | + = help: the following implementations were found: + + as Foo> error: aborting due to previous error From 76c728901e6b9d9b1c90de78c0f612f7a3fc63d5 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Tue, 4 Aug 2020 22:28:59 -0400 Subject: [PATCH 2/5] More chalk work --- compiler/rustc_middle/src/traits/chalk.rs | 38 ++ compiler/rustc_traits/src/chalk/db.rs | 79 +-- compiler/rustc_traits/src/chalk/lowering.rs | 599 +++++++++++++------- compiler/rustc_traits/src/chalk/mod.rs | 121 +--- 4 files changed, 492 insertions(+), 345 deletions(-) diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs index d03c32533f8..cc417b05ed4 100644 --- a/compiler/rustc_middle/src/traits/chalk.rs +++ b/compiler/rustc_middle/src/traits/chalk.rs @@ -109,6 +109,44 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { application_ty: &chalk_ir::ApplicationTy, fmt: &mut fmt::Formatter<'_>, ) -> Option { + match application_ty.name { + chalk_ir::TypeName::Ref(mutbl) => { + let data = application_ty.substitution.interned(); + let lifetime = match &**data[0].interned() { + chalk_ir::GenericArgData::Lifetime(t) => t, + _ => unreachable!(), + }; + let ty = match &**data[1].interned() { + chalk_ir::GenericArgData::Ty(t) => t, + _ => unreachable!(), + }; + return Some(match mutbl { + chalk_ir::Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty), + chalk_ir::Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty), + }); + } + chalk_ir::TypeName::Array => { + let data = application_ty.substitution.interned(); + let ty = match &**data[0].interned() { + chalk_ir::GenericArgData::Ty(t) => t, + _ => unreachable!(), + }; + let len = match &**data[1].interned() { + chalk_ir::GenericArgData::Const(t) => t, + _ => unreachable!(), + }; + return Some(write!(fmt, "[{:?}; {:?}]", ty, len)); + } + chalk_ir::TypeName::Slice => { + let data = application_ty.substitution.interned(); + let ty = match &**data[0].interned() { + chalk_ir::GenericArgData::Ty(t) => t, + _ => unreachable!(), + }; + return Some(write!(fmt, "[{:?}]", ty)); + } + _ => {} + } let chalk_ir::ApplicationTy { name, substitution } = application_ty; Some(write!(fmt, "{:?}{:?}", name, chalk_ir::debug::Angle(substitution.interned()))) } diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 877886ad601..23e2855f36d 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -8,7 +8,7 @@ use rustc_middle::traits::ChalkRustInterner as RustInterner; use rustc_middle::ty::subst::{InternalSubsts, Subst, SubstsRef}; -use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt}; +use rustc_middle::ty::{self, AssocItemContainer, AssocKind, TyCtxt, TypeFoldable}; use rustc_hir::def_id::DefId; use rustc_hir::Unsafety; @@ -18,11 +18,13 @@ use rustc_span::symbol::sym; use std::fmt; use std::sync::Arc; -use crate::chalk::lowering::LowerInto; +use crate::chalk::lowering::{self, LowerInto}; pub struct RustIrDatabase<'tcx> { pub tcx: TyCtxt<'tcx>, pub interner: RustInterner<'tcx>, + pub restatic_placeholder: ty::Region<'tcx>, + pub reempty_placeholder: ty::Region<'tcx>, } impl fmt::Debug for RustIrDatabase<'_> { @@ -31,6 +33,26 @@ impl fmt::Debug for RustIrDatabase<'_> { } } +impl<'tcx> RustIrDatabase<'tcx> { + fn where_clauses_for( + &self, + def_id: DefId, + bound_vars: SubstsRef<'tcx>, + ) -> Vec>> { + let predicates = self.tcx.predicates_of(def_id).predicates; + let mut regions_substitutor = lowering::RegionsSubstitutor::new( + self.tcx, + self.restatic_placeholder, + self.reempty_placeholder, + ); + predicates + .iter() + .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) + .map(|wc| wc.fold_with(&mut regions_substitutor)) + .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect() + } +} + impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'tcx> { fn interner(&self) -> &RustInterner<'tcx> { &self.interner @@ -55,11 +77,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t // FIXME(chalk): this really isn't right I don't think. The functions // for GATs are a bit hard to figure out. Are these supposed to be where // clauses or bounds? - let predicates = self.tcx.predicates_defined_on(def_id).predicates; - let where_clauses: Vec<_> = predicates - .iter() - .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) - .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); + let where_clauses = self.where_clauses_for(def_id, bound_vars); Arc::new(chalk_solve::rust_ir::AssociatedTyDatum { trait_id: chalk_ir::TraitId(trait_def_id), @@ -81,11 +99,9 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let bound_vars = bound_vars_for_item(self.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); - let predicates = self.tcx.predicates_defined_on(def_id).predicates; - let where_clauses: Vec<_> = predicates - .iter() - .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) - .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); + + let where_clauses = self.where_clauses_for(def_id, bound_vars); + let associated_ty_ids: Vec<_> = self .tcx .associated_items(def_id) @@ -140,12 +156,8 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let bound_vars = bound_vars_for_item(self.tcx, adt_def.did); let binders = binders_for(&self.interner, bound_vars); - let predicates = self.tcx.predicates_of(adt_def.did).predicates; - let where_clauses: Vec<_> = predicates - .iter() - .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) - .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)) - .collect(); + let where_clauses = self.where_clauses_for(adt_def.did, bound_vars); + let variants: Vec<_> = adt_def .variants .iter() @@ -201,14 +213,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let bound_vars = bound_vars_for_item(self.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); - let predicates = self.tcx.predicates_defined_on(def_id).predicates; - let where_clauses: Vec<_> = predicates - .iter() - .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) - .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); + let where_clauses = self.where_clauses_for(def_id, bound_vars); let sig = self.tcx.fn_sig(def_id); let inputs_and_output = sig.inputs_and_output(); + let inputs_and_output = inputs_and_output.subst(self.tcx, bound_vars); let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars( &self.interner, self.tcx, @@ -253,12 +262,14 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let trait_ref = self.tcx.impl_trait_ref(def_id).expect("not an impl"); let trait_ref = trait_ref.subst(self.tcx, bound_vars); + let mut regions_substitutor = lowering::RegionsSubstitutor::new( + self.tcx, + self.restatic_placeholder, + self.reempty_placeholder, + ); + let trait_ref = trait_ref.fold_with(&mut regions_substitutor); - let predicates = self.tcx.predicates_of(def_id).predicates; - let where_clauses: Vec<_> = predicates - .iter() - .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) - .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); + let where_clauses = self.where_clauses_for(def_id, bound_vars); let value = chalk_solve::rust_ir::ImplDatumBound { trait_ref: trait_ref.lower_into(&self.interner), @@ -293,6 +304,12 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t let self_ty = trait_ref.self_ty(); let self_ty = self_ty.subst(self.tcx, bound_vars); + let mut regions_substitutor = lowering::RegionsSubstitutor::new( + self.tcx, + self.restatic_placeholder, + self.reempty_placeholder, + ); + let self_ty = self_ty.fold_with(&mut regions_substitutor); let lowered_ty = self_ty.lower_into(&self.interner); parameters[0].assert_ty_ref(&self.interner).could_match(&self.interner, &lowered_ty) @@ -370,11 +387,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ) -> Arc>> { let bound_vars = bound_vars_for_item(self.tcx, opaque_ty_id.0); let binders = binders_for(&self.interner, bound_vars); - let predicates = self.tcx.predicates_defined_on(opaque_ty_id.0).predicates; - let where_clauses: Vec<_> = predicates - .iter() - .map(|(wc, _)| wc.subst(self.tcx, &bound_vars)) - .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect(); + let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars); let value = chalk_solve::rust_ir::OpaqueTyDatumBound { bounds: chalk_ir::Binders::new(binders.clone(), vec![]), diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index b5332383988..c2a3fa22dc8 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -60,6 +60,12 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution>> for Subst } } +impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution> { + fn lower_into(self, interner: &RustInterner<'tcx>) -> SubstsRef<'tcx> { + interner.tcx.mk_substs(self.iter(interner).map(|subst| subst.lower_into(interner))) + } +} + impl<'tcx> LowerInto<'tcx, chalk_ir::AliasTy>> for ty::ProjectionTy<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::AliasTy> { chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { @@ -76,104 +82,29 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment, ) -> chalk_ir::InEnvironment>> { - let clauses = self.environment.into_iter().filter_map(|clause| match clause { + let clauses = self.environment.into_iter().map(|clause| match clause { ChalkEnvironmentClause::Predicate(predicate) => { - // FIXME(chalk): forall - match predicate.bound_atom(interner.tcx).skip_binder() { - ty::PredicateAtom::Trait(predicate, _) => { - let predicate = ty::Binder::bind(predicate); - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &predicate); - - Some( - chalk_ir::ProgramClauseData(chalk_ir::Binders::new( - binders, - chalk_ir::ProgramClauseImplication { - consequence: chalk_ir::DomainGoal::FromEnv( - chalk_ir::FromEnv::Trait( - predicate.trait_ref.lower_into(interner), - ), - ), - conditions: chalk_ir::Goals::empty(interner), - priority: chalk_ir::ClausePriority::High, - constraints: chalk_ir::Constraints::empty(interner), - }, - )) - .intern(interner), - ) - } - ty::PredicateAtom::RegionOutlives(predicate) => { - let predicate = ty::Binder::bind(predicate); - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &predicate); - - Some( - chalk_ir::ProgramClauseData(chalk_ir::Binders::new( - binders, - chalk_ir::ProgramClauseImplication { - consequence: chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::LifetimeOutlives( - chalk_ir::LifetimeOutlives { - a: predicate.0.lower_into(interner), - b: predicate.1.lower_into(interner), - }, - ), - ), - conditions: chalk_ir::Goals::empty(interner), - priority: chalk_ir::ClausePriority::High, - constraints: chalk_ir::Constraints::empty(interner), - }, - )) - .intern(interner), - ) - } - ty::PredicateAtom::TypeOutlives(predicate) => { - let predicate = ty::Binder::bind(predicate); - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &predicate); - - Some( - chalk_ir::ProgramClauseData(chalk_ir::Binders::new( - binders, - chalk_ir::ProgramClauseImplication { - consequence: chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::TypeOutlives( - chalk_ir::TypeOutlives { - ty: predicate.0.lower_into(interner), - lifetime: predicate.1.lower_into(interner), - }, - ), - ), - conditions: chalk_ir::Goals::empty(interner), - priority: chalk_ir::ClausePriority::High, - constraints: chalk_ir::Constraints::empty(interner), - }, - )) - .intern(interner), - ) - } - ty::PredicateAtom::Projection(predicate) => { - let predicate = ty::Binder::bind(predicate); - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &predicate); - - Some( - chalk_ir::ProgramClauseData(chalk_ir::Binders::new( - binders, - chalk_ir::ProgramClauseImplication { - consequence: chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::AliasEq( - predicate.lower_into(interner), - ), - ), - conditions: chalk_ir::Goals::empty(interner), - priority: chalk_ir::ClausePriority::High, - constraints: chalk_ir::Constraints::empty(interner), - }, - )) - .intern(interner), - ) - } + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, &predicate.bound_atom(interner.tcx)); + let consequence = match predicate { + ty::PredicateAtom::Trait(predicate, _) => chalk_ir::DomainGoal::FromEnv( + chalk_ir::FromEnv::Trait(predicate.trait_ref.lower_into(interner)), + ), + ty::PredicateAtom::RegionOutlives(predicate) => chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { + a: predicate.0.lower_into(interner), + b: predicate.1.lower_into(interner), + }), + ), + ty::PredicateAtom::TypeOutlives(predicate) => chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives { + ty: predicate.0.lower_into(interner), + lifetime: predicate.1.lower_into(interner), + }), + ), + ty::PredicateAtom::Projection(predicate) => chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)), + ), ty::PredicateAtom::WellFormed(..) | ty::PredicateAtom::ObjectSafe(..) | ty::PredicateAtom::ClosureKind(..) @@ -182,9 +113,16 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment { bug!("unexpected predicate {}", predicate) } - } + }; + let value = chalk_ir::ProgramClauseImplication { + consequence, + conditions: chalk_ir::Goals::empty(interner), + priority: chalk_ir::ClausePriority::High, + constraints: chalk_ir::Constraints::empty(interner), + }; + chalk_ir::ProgramClauseData(chalk_ir::Binders::new(binders, value)).intern(interner) } - ChalkEnvironmentClause::TypeFromEnv(ty) => Some( + ChalkEnvironmentClause::TypeFromEnv(ty) => { chalk_ir::ProgramClauseData(chalk_ir::Binders::new( chalk_ir::VariableKinds::empty(interner), chalk_ir::ProgramClauseImplication { @@ -196,8 +134,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment> = self.goal.lower_into(&interner); @@ -212,36 +150,35 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predicate<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData> { - // FIXME(chalk): forall - match self.bound_atom(interner.tcx).skip_binder() { + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, &self.bound_atom(interner.tcx)); + + let value = match predicate { ty::PredicateAtom::Trait(predicate, _) => { - ty::Binder::bind(predicate).lower_into(interner) + chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)), + )) } ty::PredicateAtom::RegionOutlives(predicate) => { - let predicate = ty::Binder::bind(predicate); - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &predicate); - - chalk_ir::GoalData::Quantified( - chalk_ir::QuantifierKind::ForAll, - chalk_ir::Binders::new( - binders, - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { - a: predicate.0.lower_into(interner), - b: predicate.1.lower_into(interner), - }), - )) - .intern(interner), - ), - ) + chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { + a: predicate.0.lower_into(interner), + b: predicate.1.lower_into(interner), + }), + )) } - // FIXME(chalk): TypeOutlives - ty::PredicateAtom::TypeOutlives(_predicate) => { - chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) + ty::PredicateAtom::TypeOutlives(predicate) => { + chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives { + ty: predicate.0.lower_into(interner), + lifetime: predicate.1.lower_into(interner), + }), + )) } ty::PredicateAtom::Projection(predicate) => { - ty::Binder::bind(predicate).lower_into(interner) + chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( + chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)), + )) } ty::PredicateAtom::WellFormed(arg) => match arg.unpack() { GenericArgKind::Type(ty) => match ty.kind() { @@ -252,21 +189,9 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } - _ => { - let (ty, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &ty::Binder::bind(ty)); - - chalk_ir::GoalData::Quantified( - chalk_ir::QuantifierKind::ForAll, - chalk_ir::Binders::new( - binders, - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::WellFormed( - chalk_ir::WellFormed::Ty(ty.lower_into(interner)), - )) - .intern(interner), - ), - ) - } + _ => chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::WellFormed( + chalk_ir::WellFormed::Ty(ty.lower_into(interner)), + )), }, // FIXME(chalk): handle well formed consts GenericArgKind::Const(..) => { @@ -289,7 +214,12 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predi | ty::PredicateAtom::ConstEquate(..) => { chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) } - } + }; + + chalk_ir::GoalData::Quantified( + chalk_ir::QuantifierKind::ForAll, + chalk_ir::Binders::new(binders, value.intern(interner)), + ) } } @@ -304,25 +234,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::TraitRef>> } } -impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> - for ty::PolyTraitPredicate<'tcx> -{ - fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData> { - let (ty, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &self); - - chalk_ir::GoalData::Quantified( - chalk_ir::QuantifierKind::ForAll, - chalk_ir::Binders::new( - binders, - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::Implemented(ty.trait_ref.lower_into(interner)), - )) - .intern(interner), - ), - ) - } -} - impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq>> for rustc_middle::ty::ProjectionPredicate<'tcx> { @@ -334,25 +245,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq>> } } -impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> - for ty::PolyProjectionPredicate<'tcx> -{ - fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData> { - let (ty, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &self); - - chalk_ir::GoalData::Quantified( - chalk_ir::QuantifierKind::ForAll, - chalk_ir::Binders::new( - binders, - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::AliasEq(ty.lower_into(interner)), - )) - .intern(interner), - ), - ) - } -} - impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Ty> { use chalk_ir::TyData; @@ -393,7 +285,8 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { ast::FloatTy::F64 => float(chalk_ir::FloatTy::F64), }, Adt(def, substs) => apply(struct_ty(def.did), substs.lower_into(interner)), - Foreign(_def_id) => unimplemented!(), + // FIXME(chalk): lower Foreign + Foreign(def_id) => apply(chalk_ir::TypeName::FnDef(chalk_ir::FnDefId(def_id)), empty()), Str => apply(chalk_ir::TypeName::Str, empty()), Array(ty, len) => { let value = match len.val { @@ -520,6 +413,111 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { } } +impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty> { + fn lower_into(self, interner: &RustInterner<'tcx>) -> Ty<'tcx> { + use chalk_ir::TyData; + use rustc_ast::ast; + + let kind = match self.data(interner) { + TyData::Apply(application_ty) => match application_ty.name { + chalk_ir::TypeName::Adt(struct_id) => { + ty::Adt(struct_id.0, application_ty.substitution.lower_into(interner)) + } + chalk_ir::TypeName::Scalar(scalar) => match scalar { + chalk_ir::Scalar::Bool => ty::Bool, + chalk_ir::Scalar::Char => ty::Char, + chalk_ir::Scalar::Int(int_ty) => match int_ty { + chalk_ir::IntTy::Isize => ty::Int(ast::IntTy::Isize), + chalk_ir::IntTy::I8 => ty::Int(ast::IntTy::I8), + chalk_ir::IntTy::I16 => ty::Int(ast::IntTy::I16), + chalk_ir::IntTy::I32 => ty::Int(ast::IntTy::I32), + chalk_ir::IntTy::I64 => ty::Int(ast::IntTy::I64), + chalk_ir::IntTy::I128 => ty::Int(ast::IntTy::I128), + }, + chalk_ir::Scalar::Uint(int_ty) => match int_ty { + chalk_ir::UintTy::Usize => ty::Uint(ast::UintTy::Usize), + chalk_ir::UintTy::U8 => ty::Uint(ast::UintTy::U8), + chalk_ir::UintTy::U16 => ty::Uint(ast::UintTy::U16), + chalk_ir::UintTy::U32 => ty::Uint(ast::UintTy::U32), + chalk_ir::UintTy::U64 => ty::Uint(ast::UintTy::U64), + chalk_ir::UintTy::U128 => ty::Uint(ast::UintTy::U128), + }, + chalk_ir::Scalar::Float(float_ty) => match float_ty { + chalk_ir::FloatTy::F32 => ty::Float(ast::FloatTy::F32), + chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64), + }, + }, + chalk_ir::TypeName::Array => unimplemented!(), + chalk_ir::TypeName::FnDef(id) => { + ty::FnDef(id.0, application_ty.substitution.lower_into(interner)) + } + chalk_ir::TypeName::Closure(closure) => { + ty::Closure(closure.0, application_ty.substitution.lower_into(interner)) + } + chalk_ir::TypeName::Never => ty::Never, + chalk_ir::TypeName::Tuple(_size) => { + ty::Tuple(application_ty.substitution.lower_into(interner)) + } + chalk_ir::TypeName::Slice => ty::Slice( + application_ty.substitution.as_slice(interner)[0] + .ty(interner) + .unwrap() + .lower_into(interner), + ), + chalk_ir::TypeName::Raw(mutbl) => ty::RawPtr(ty::TypeAndMut { + ty: application_ty.substitution.as_slice(interner)[0] + .ty(interner) + .unwrap() + .lower_into(interner), + mutbl: match mutbl { + chalk_ir::Mutability::Mut => ast::Mutability::Mut, + chalk_ir::Mutability::Not => ast::Mutability::Not, + }, + }), + chalk_ir::TypeName::Ref(mutbl) => ty::Ref( + application_ty.substitution.as_slice(interner)[0] + .lifetime(interner) + .unwrap() + .lower_into(interner), + application_ty.substitution.as_slice(interner)[1] + .ty(interner) + .unwrap() + .lower_into(interner), + match mutbl { + chalk_ir::Mutability::Mut => ast::Mutability::Mut, + chalk_ir::Mutability::Not => ast::Mutability::Not, + }, + ), + chalk_ir::TypeName::Str => ty::Str, + chalk_ir::TypeName::OpaqueType(opaque_ty) => { + ty::Opaque(opaque_ty.0, application_ty.substitution.lower_into(interner)) + } + chalk_ir::TypeName::AssociatedType(assoc_ty) => ty::Projection(ty::ProjectionTy { + substs: application_ty.substitution.lower_into(interner), + item_def_id: assoc_ty.0, + }), + chalk_ir::TypeName::Error => unimplemented!(), + }, + TyData::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder { + universe: ty::UniverseIndex::from_usize(placeholder.ui.counter), + name: ty::BoundVar::from_usize(placeholder.idx), + }), + TyData::Alias(_alias_ty) => unimplemented!(), + TyData::Function(_quantified_ty) => unimplemented!(), + TyData::BoundVar(_bound) => ty::Bound( + ty::DebruijnIndex::from_usize(_bound.debruijn.depth() as usize), + ty::BoundTy { + var: ty::BoundVar::from_usize(_bound.index), + kind: ty::BoundTyKind::Anon, + }, + ), + TyData::InferenceVar(_, _) => unimplemented!(), + TyData::Dyn(_) => unimplemented!(), + }; + interner.tcx.mk_ty(kind) + } +} + impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Lifetime> { use rustc_middle::ty::RegionKind::*; @@ -557,6 +555,59 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'t } } +impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime> { + fn lower_into(self, interner: &RustInterner<'tcx>) -> Region<'tcx> { + let kind = match self.data(interner) { + chalk_ir::LifetimeData::BoundVar(var) => ty::RegionKind::ReLateBound( + ty::DebruijnIndex::from_u32(var.debruijn.depth()), + ty::BoundRegion::BrAnon(var.index as u32), + ), + chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(), + chalk_ir::LifetimeData::Placeholder(p) => { + ty::RegionKind::RePlaceholder(ty::Placeholder { + universe: ty::UniverseIndex::from_usize(p.ui.counter), + name: ty::BoundRegion::BrAnon(p.idx as u32), + }) + } + chalk_ir::LifetimeData::Phantom(_, _) => unimplemented!(), + }; + interner.tcx.mk_region(kind) + } +} + +impl<'tcx> LowerInto<'tcx, chalk_ir::Const>> for ty::Const<'tcx> { + fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::Const> { + let ty = self.ty.lower_into(interner); + let value = match self.val { + ty::ConstKind::Value(val) => { + chalk_ir::ConstValue::Concrete(chalk_ir::ConcreteConst { interned: val }) + } + ty::ConstKind::Bound(db, bound) => chalk_ir::ConstValue::BoundVar( + chalk_ir::BoundVar::new(chalk_ir::DebruijnIndex::new(db.as_u32()), bound.index()), + ), + _ => unimplemented!("Const not implemented. {:?}", self), + }; + chalk_ir::ConstData { ty, value }.intern(interner) + } +} + +impl<'tcx> LowerInto<'tcx, ty::Const<'tcx>> for &chalk_ir::Const> { + fn lower_into(self, interner: &RustInterner<'tcx>) -> ty::Const<'tcx> { + let data = self.data(interner); + let ty = data.ty.lower_into(interner); + let val = match data.value { + chalk_ir::ConstValue::BoundVar(var) => ty::ConstKind::Bound( + ty::DebruijnIndex::from_u32(var.debruijn.depth()), + ty::BoundVar::from_u32(var.index as u32), + ), + chalk_ir::ConstValue::InferenceVar(_var) => unimplemented!(), + chalk_ir::ConstValue::Placeholder(_p) => unimplemented!(), + chalk_ir::ConstValue::Concrete(c) => ty::ConstKind::Value(c.interned), + }; + ty::Const { ty, val } + } +} + impl<'tcx> LowerInto<'tcx, chalk_ir::GenericArg>> for GenericArg<'tcx> { fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GenericArg> { match self.unpack() { @@ -566,18 +617,35 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::GenericArg>> for Generic ty::subst::GenericArgKind::Lifetime(lifetime) => { chalk_ir::GenericArgData::Lifetime(lifetime.lower_into(interner)) } - ty::subst::GenericArgKind::Const(_) => chalk_ir::GenericArgData::Ty( - chalk_ir::TyData::Apply(chalk_ir::ApplicationTy { - name: chalk_ir::TypeName::Tuple(0), - substitution: chalk_ir::Substitution::empty(interner), - }) - .intern(interner), - ), + ty::subst::GenericArgKind::Const(c) => { + chalk_ir::GenericArgData::Const(c.lower_into(interner)) + } } .intern(interner) } } +impl<'tcx> LowerInto<'tcx, ty::subst::GenericArg<'tcx>> + for &chalk_ir::GenericArg> +{ + fn lower_into(self, interner: &RustInterner<'tcx>) -> ty::subst::GenericArg<'tcx> { + match self.data(interner) { + chalk_ir::GenericArgData::Ty(ty) => { + let t: Ty<'tcx> = ty.lower_into(interner); + t.into() + } + chalk_ir::GenericArgData::Lifetime(lifetime) => { + let r: Region<'tcx> = lifetime.lower_into(interner); + r.into() + } + chalk_ir::GenericArgData::Const(c) => { + let c: ty::Const<'tcx> = c.lower_into(interner); + interner.tcx.mk_const(c).into() + } + } + } +} + // We lower into an Option here since there are some predicates which Chalk // doesn't have a representation for yet (as a `WhereClause`), but are so common // that we just are accepting the unsoundness for now. The `Option` will @@ -589,33 +657,27 @@ impl<'tcx> LowerInto<'tcx, Option, ) -> Option>> { - // FIXME(chalk): forall - match self.bound_atom(interner.tcx).skip_binder() { + let (predicate, binders, _named_regions) = + collect_bound_vars(interner, interner.tcx, &self.bound_atom(interner.tcx)); + let value = match predicate { ty::PredicateAtom::Trait(predicate, _) => { - let predicate = ty::Binder::bind(predicate); - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &predicate); - - Some(chalk_ir::Binders::new( - binders, - chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)), - )) + Some(chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner))) } ty::PredicateAtom::RegionOutlives(predicate) => { - let predicate = ty::Binder::bind(predicate); - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, &predicate); - - Some(chalk_ir::Binders::new( - binders, - chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { - a: predicate.0.lower_into(interner), - b: predicate.1.lower_into(interner), - }), - )) + Some(chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { + a: predicate.0.lower_into(interner), + b: predicate.1.lower_into(interner), + })) + } + ty::PredicateAtom::TypeOutlives(predicate) => { + Some(chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives { + ty: predicate.0.lower_into(interner), + lifetime: predicate.1.lower_into(interner), + })) + } + ty::PredicateAtom::Projection(predicate) => { + Some(chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner))) } - ty::PredicateAtom::TypeOutlives(_predicate) => None, - ty::PredicateAtom::Projection(_predicate) => None, ty::PredicateAtom::WellFormed(_ty) => None, ty::PredicateAtom::ObjectSafe(..) @@ -623,7 +685,8 @@ impl<'tcx> LowerInto<'tcx, Option bug!("unexpected predicate {}", &self), - } + }; + value.map(|value| chalk_ir::Binders::new(binders, value)) } } @@ -636,13 +699,21 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders chalk_ir::Binders>> { let (predicates, binders, _named_regions) = collect_bound_vars(interner, interner.tcx, &self); + let self_ty = interner.tcx.mk_ty(ty::Bound( + // This is going to be wrapped in a binder + ty::DebruijnIndex::from_usize(1), + ty::BoundTy { var: ty::BoundVar::from_usize(0), kind: ty::BoundTyKind::Anon }, + )); let where_clauses = predicates.into_iter().map(|predicate| match predicate { ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => { chalk_ir::Binders::new( chalk_ir::VariableKinds::empty(interner), chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { trait_id: chalk_ir::TraitId(def_id), - substitution: substs.lower_into(interner), + substitution: interner + .tcx + .mk_substs_trait(self_ty, substs) + .lower_into(interner), }), ) } @@ -651,7 +722,7 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Binders { tcx: TyCtxt<'tcx>, binder_index: ty::DebruijnIndex, list: Vec, + next_ty_placehoder: usize, crate params: rustc_data_structures::fx::FxHashMap, crate named_regions: BTreeMap, } impl<'tcx> ParamsSubstitutor<'tcx> { - crate fn new(tcx: TyCtxt<'tcx>) -> Self { + crate fn new(tcx: TyCtxt<'tcx>, next_ty_placehoder: usize) -> Self { ParamsSubstitutor { tcx, binder_index: ty::INNERMOST, list: vec![], + next_ty_placehoder, params: rustc_data_structures::fx::FxHashMap::default(), named_regions: BTreeMap::default(), } @@ -878,13 +951,13 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { // first pass to collect placeholders. Then we can insert params after. ty::Placeholder(_) => unimplemented!(), ty::Param(param) => match self.list.iter().position(|r| r == ¶m) { - Some(_idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { + Some(idx) => self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), - name: ty::BoundVar::from_usize(_idx), + name: ty::BoundVar::from_usize(idx), })), None => { self.list.push(param); - let idx = self.list.len() - 1; + let idx = self.list.len() - 1 + self.next_ty_placehoder; self.params.insert(idx, param); self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), @@ -920,3 +993,95 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { } } } + +/// Used to collect `Placeholder`s. +crate struct PlaceholdersCollector { + universe_index: ty::UniverseIndex, + crate next_ty_placehoder: usize, + crate next_anon_region_placeholder: u32, +} + +impl PlaceholdersCollector { + crate fn new() -> Self { + PlaceholdersCollector { + universe_index: ty::UniverseIndex::ROOT, + next_ty_placehoder: 0, + next_anon_region_placeholder: 0, + } + } +} + +impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { + fn visit_binder>(&mut self, t: &Binder) -> bool { + t.super_visit_with(self) + } + + fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { + match t.kind { + ty::Placeholder(p) if p.universe == self.universe_index => { + self.next_ty_placehoder = self.next_ty_placehoder.max(p.name.as_usize() + 1); + } + + _ => (), + }; + + t.super_visit_with(self) + } + + fn visit_region(&mut self, r: Region<'tcx>) -> bool { + match r { + ty::RePlaceholder(p) if p.universe == self.universe_index => { + if let ty::BoundRegion::BrAnon(anon) = p.name { + self.next_anon_region_placeholder = self.next_anon_region_placeholder.max(anon); + } + } + + _ => (), + }; + + r.super_visit_with(self) + } +} + +/// Used to substitute specific `Regions`s with placeholders. +crate struct RegionsSubstitutor<'tcx> { + tcx: TyCtxt<'tcx>, + restatic_placeholder: ty::Region<'tcx>, + reempty_placeholder: ty::Region<'tcx>, +} + +impl<'tcx> RegionsSubstitutor<'tcx> { + crate fn new( + tcx: TyCtxt<'tcx>, + restatic_placeholder: ty::Region<'tcx>, + reempty_placeholder: ty::Region<'tcx>, + ) -> Self { + RegionsSubstitutor { tcx, restatic_placeholder, reempty_placeholder } + } +} + +impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> { + fn tcx<'b>(&'b self) -> TyCtxt<'tcx> { + self.tcx + } + + fn fold_binder>(&mut self, t: &Binder) -> Binder { + t.super_fold_with(self) + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + t.super_fold_with(self) + } + + fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { + match r { + ty::ReStatic => self.restatic_placeholder, + ty::ReEmpty(ui) => { + assert_eq!(ui.as_usize(), 0); + self.reempty_placeholder + } + + _ => r.super_fold_with(self), + } + } +} diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index 52648477f02..a8e5bae0fc4 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -15,9 +15,7 @@ use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind}; use rustc_middle::traits::ChalkRustInterner; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::GenericArg; -use rustc_middle::ty::{ - self, Bound, BoundVar, ParamTy, Region, RegionKind, Ty, TyCtxt, TypeFoldable, -}; +use rustc_middle::ty::{self, BoundVar, ParamTy, TyCtxt, TypeFoldable}; use rustc_infer::infer::canonical::{ Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse, @@ -25,7 +23,9 @@ use rustc_infer::infer::canonical::{ use rustc_infer::traits::{self, ChalkCanonicalGoal}; use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase; -use crate::chalk::lowering::{LowerInto, ParamsSubstitutor}; +use crate::chalk::lowering::{ + LowerInto, ParamsSubstitutor, PlaceholdersCollector, RegionsSubstitutor, +}; use chalk_solve::Solution; @@ -40,9 +40,27 @@ crate fn evaluate_goal<'tcx>( let interner = ChalkRustInterner { tcx }; // Chalk doesn't have a notion of `Params`, so instead we use placeholders. - let mut params_substitutor = ParamsSubstitutor::new(tcx); + let mut placeholders_collector = PlaceholdersCollector::new(); + obligation.visit_with(&mut placeholders_collector); + + let restatic_placeholder = tcx.mk_region(ty::RegionKind::RePlaceholder(ty::Placeholder { + universe: ty::UniverseIndex::ROOT, + name: ty::BoundRegion::BrAnon(placeholders_collector.next_anon_region_placeholder), + })); + let reempty_placeholder = tcx.mk_region(ty::RegionKind::RePlaceholder(ty::Placeholder { + universe: ty::UniverseIndex::ROOT, + name: ty::BoundRegion::BrAnon(placeholders_collector.next_anon_region_placeholder + 1), + })); + + let mut params_substitutor = + ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placehoder); let obligation = obligation.fold_with(&mut params_substitutor); let _params: FxHashMap = params_substitutor.params; + + let mut regions_substitutor = + RegionsSubstitutor::new(tcx, restatic_placeholder, reempty_placeholder); + let obligation = obligation.fold_with(&mut regions_substitutor); + let max_universe = obligation.max_universe.index(); let _lowered_goal: chalk_ir::UCanonical< @@ -83,7 +101,7 @@ crate fn evaluate_goal<'tcx>( use chalk_solve::Solver; let mut solver = chalk_engine::solve::SLGSolver::new(32, None); - let db = ChalkRustIrDatabase { tcx, interner }; + let db = ChalkRustIrDatabase { tcx, interner, restatic_placeholder, reempty_placeholder }; let solution = chalk_solve::logging::with_tracing_logs(|| solver.solve(&db, &_lowered_goal)); // Ideally, the code to convert *back* to rustc types would live close to @@ -94,94 +112,7 @@ crate fn evaluate_goal<'tcx>( let make_solution = |_subst: chalk_ir::Substitution<_>| { let mut var_values: IndexVec> = IndexVec::new(); _subst.as_slice(&interner).iter().for_each(|p| { - // FIXME(chalk): we should move this elsewhere, since this is - // essentially inverse of lowering a `GenericArg`. - let _data = p.data(&interner); - match _data { - chalk_ir::GenericArgData::Ty(_t) => { - use chalk_ir::TyData; - use rustc_ast as ast; - - let _data = _t.data(&interner); - let kind = match _data { - TyData::Apply(_application_ty) => match _application_ty.name { - chalk_ir::TypeName::Adt(_struct_id) => unimplemented!(), - chalk_ir::TypeName::Scalar(scalar) => match scalar { - chalk_ir::Scalar::Bool => ty::Bool, - chalk_ir::Scalar::Char => ty::Char, - chalk_ir::Scalar::Int(int_ty) => match int_ty { - chalk_ir::IntTy::Isize => ty::Int(ast::IntTy::Isize), - chalk_ir::IntTy::I8 => ty::Int(ast::IntTy::I8), - chalk_ir::IntTy::I16 => ty::Int(ast::IntTy::I16), - chalk_ir::IntTy::I32 => ty::Int(ast::IntTy::I32), - chalk_ir::IntTy::I64 => ty::Int(ast::IntTy::I64), - chalk_ir::IntTy::I128 => ty::Int(ast::IntTy::I128), - }, - chalk_ir::Scalar::Uint(int_ty) => match int_ty { - chalk_ir::UintTy::Usize => ty::Uint(ast::UintTy::Usize), - chalk_ir::UintTy::U8 => ty::Uint(ast::UintTy::U8), - chalk_ir::UintTy::U16 => ty::Uint(ast::UintTy::U16), - chalk_ir::UintTy::U32 => ty::Uint(ast::UintTy::U32), - chalk_ir::UintTy::U64 => ty::Uint(ast::UintTy::U64), - chalk_ir::UintTy::U128 => ty::Uint(ast::UintTy::U128), - }, - chalk_ir::Scalar::Float(float_ty) => match float_ty { - chalk_ir::FloatTy::F32 => ty::Float(ast::FloatTy::F32), - chalk_ir::FloatTy::F64 => ty::Float(ast::FloatTy::F64), - }, - }, - chalk_ir::TypeName::Array => unimplemented!(), - chalk_ir::TypeName::FnDef(_) => unimplemented!(), - chalk_ir::TypeName::Closure(_) => unimplemented!(), - chalk_ir::TypeName::Never => unimplemented!(), - chalk_ir::TypeName::Tuple(_size) => unimplemented!(), - chalk_ir::TypeName::Slice => unimplemented!(), - chalk_ir::TypeName::Raw(_) => unimplemented!(), - chalk_ir::TypeName::Ref(_) => unimplemented!(), - chalk_ir::TypeName::Str => unimplemented!(), - chalk_ir::TypeName::OpaqueType(_ty) => unimplemented!(), - chalk_ir::TypeName::AssociatedType(_assoc_ty) => unimplemented!(), - chalk_ir::TypeName::Error => unimplemented!(), - }, - TyData::Placeholder(_placeholder) => { - unimplemented!(); - } - TyData::Alias(_alias_ty) => unimplemented!(), - TyData::Function(_quantified_ty) => unimplemented!(), - TyData::BoundVar(_bound) => Bound( - ty::DebruijnIndex::from_usize(_bound.debruijn.depth() as usize), - ty::BoundTy { - var: ty::BoundVar::from_usize(_bound.index), - kind: ty::BoundTyKind::Anon, - }, - ), - TyData::InferenceVar(_, _) => unimplemented!(), - TyData::Dyn(_) => unimplemented!(), - }; - let _ty: Ty<'_> = tcx.mk_ty(kind); - let _arg: GenericArg<'_> = _ty.into(); - var_values.push(_arg); - } - chalk_ir::GenericArgData::Lifetime(_l) => { - let _data = _l.data(&interner); - let _lifetime: Region<'_> = match _data { - chalk_ir::LifetimeData::BoundVar(_var) => { - tcx.mk_region(RegionKind::ReLateBound( - rustc_middle::ty::DebruijnIndex::from_usize( - _var.debruijn.depth() as usize - ), - rustc_middle::ty::BoundRegion::BrAnon(_var.index as u32), - )) - } - chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(), - chalk_ir::LifetimeData::Placeholder(_index) => unimplemented!(), - chalk_ir::LifetimeData::Phantom(_, _) => unimplemented!(), - }; - let _arg: GenericArg<'_> = _lifetime.into(); - var_values.push(_arg); - } - chalk_ir::GenericArgData::Const(_) => unimplemented!(), - } + var_values.push(p.lower_into(&interner)); }); let sol = Canonical { max_universe: ty::UniverseIndex::from_usize(0), @@ -193,7 +124,7 @@ crate fn evaluate_goal<'tcx>( value: (), }, }; - &*tcx.arena.alloc(sol) + tcx.arena.alloc(sol) }; solution .map(|s| match s { From f6905694658e2f239c7054f063e962d9097dd1be Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Sat, 15 Aug 2020 18:04:11 -0400 Subject: [PATCH 3/5] Review comments --- compiler/rustc_middle/src/traits/chalk.rs | 42 +++-- compiler/rustc_traits/src/chalk/db.rs | 166 +++++++++++--------- compiler/rustc_traits/src/chalk/lowering.rs | 30 +--- compiler/rustc_traits/src/chalk/mod.rs | 23 +-- 4 files changed, 130 insertions(+), 131 deletions(-) diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs index cc417b05ed4..763b078e770 100644 --- a/compiler/rustc_middle/src/traits/chalk.rs +++ b/compiler/rustc_middle/src/traits/chalk.rs @@ -112,30 +112,25 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { match application_ty.name { chalk_ir::TypeName::Ref(mutbl) => { let data = application_ty.substitution.interned(); - let lifetime = match &**data[0].interned() { - chalk_ir::GenericArgData::Lifetime(t) => t, + match (&**data[0].interned(), &**data[1].interned()) { + ( + chalk_ir::GenericArgData::Lifetime(lifetime), + chalk_ir::GenericArgData::Ty(ty), + ) => Some(match mutbl { + chalk_ir::Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty), + chalk_ir::Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty), + }), _ => unreachable!(), - }; - let ty = match &**data[1].interned() { - chalk_ir::GenericArgData::Ty(t) => t, - _ => unreachable!(), - }; - return Some(match mutbl { - chalk_ir::Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty), - chalk_ir::Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty), - }); + } } chalk_ir::TypeName::Array => { let data = application_ty.substitution.interned(); - let ty = match &**data[0].interned() { - chalk_ir::GenericArgData::Ty(t) => t, + match (&**data[0].interned(), &**data[1].interned()) { + (chalk_ir::GenericArgData::Ty(ty), chalk_ir::GenericArgData::Const(len)) => { + Some(write!(fmt, "[{:?}; {:?}]", ty, len)) + } _ => unreachable!(), - }; - let len = match &**data[1].interned() { - chalk_ir::GenericArgData::Const(t) => t, - _ => unreachable!(), - }; - return Some(write!(fmt, "[{:?}; {:?}]", ty, len)); + } } chalk_ir::TypeName::Slice => { let data = application_ty.substitution.interned(); @@ -143,12 +138,13 @@ impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { chalk_ir::GenericArgData::Ty(t) => t, _ => unreachable!(), }; - return Some(write!(fmt, "[{:?}]", ty)); + Some(write!(fmt, "[{:?}]", ty)) + } + _ => { + let chalk_ir::ApplicationTy { name, substitution } = application_ty; + Some(write!(fmt, "{:?}{:?}", name, chalk_ir::debug::Angle(substitution.interned()))) } - _ => {} } - let chalk_ir::ApplicationTy { name, substitution } = application_ty; - Some(write!(fmt, "{:?}{:?}", name, chalk_ir::debug::Angle(substitution.interned()))) } fn debug_substitution( diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index 23e2855f36d..7cc567dabb2 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -21,10 +21,9 @@ use std::sync::Arc; use crate::chalk::lowering::{self, LowerInto}; pub struct RustIrDatabase<'tcx> { - pub tcx: TyCtxt<'tcx>, - pub interner: RustInterner<'tcx>, - pub restatic_placeholder: ty::Region<'tcx>, - pub reempty_placeholder: ty::Region<'tcx>, + pub(crate) interner: RustInterner<'tcx>, + pub(crate) restatic_placeholder: ty::Region<'tcx>, + pub(crate) reempty_placeholder: ty::Region<'tcx>, } impl fmt::Debug for RustIrDatabase<'_> { @@ -39,15 +38,15 @@ impl<'tcx> RustIrDatabase<'tcx> { def_id: DefId, bound_vars: SubstsRef<'tcx>, ) -> Vec>> { - let predicates = self.tcx.predicates_of(def_id).predicates; + let predicates = self.interner.tcx.predicates_of(def_id).predicates; let mut regions_substitutor = lowering::RegionsSubstitutor::new( - self.tcx, + self.interner.tcx, self.restatic_placeholder, self.reempty_placeholder, ); predicates .iter() - .map(|(wc, _)| wc.subst(self.tcx, bound_vars)) + .map(|(wc, _)| wc.subst(self.interner.tcx, bound_vars)) .map(|wc| wc.fold_with(&mut regions_substitutor)) .filter_map(|wc| LowerInto::>>>::lower_into(wc, &self.interner)).collect() } @@ -63,7 +62,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t assoc_type_id: chalk_ir::AssocTypeId>, ) -> Arc>> { let def_id = assoc_type_id.0; - let assoc_item = self.tcx.associated_item(def_id); + let assoc_item = self.interner.tcx.associated_item(def_id); let trait_def_id = match assoc_item.container { AssocItemContainer::TraitContainer(def_id) => def_id, _ => unimplemented!("Not possible??"), @@ -72,7 +71,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t AssocKind::Type => {} _ => unimplemented!("Not possible??"), } - let bound_vars = bound_vars_for_item(self.tcx, def_id); + let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); // FIXME(chalk): this really isn't right I don't think. The functions // for GATs are a bit hard to figure out. Are these supposed to be where @@ -95,14 +94,15 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t trait_id: chalk_ir::TraitId>, ) -> Arc>> { let def_id = trait_id.0; - let trait_def = self.tcx.trait_def(def_id); + let trait_def = self.interner.tcx.trait_def(def_id); - let bound_vars = bound_vars_for_item(self.tcx, def_id); + let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); let where_clauses = self.where_clauses_for(def_id, bound_vars); let associated_ty_ids: Vec<_> = self + .interner .tcx .associated_items(def_id) .in_definition_order() @@ -110,24 +110,47 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t .map(|i| chalk_ir::AssocTypeId(i.def_id)) .collect(); - let well_known = - if self.tcx.lang_items().sized_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_solve::rust_ir::WellKnownTrait::Sized) - } else if self.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_solve::rust_ir::WellKnownTrait::Copy) - } else if self.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_solve::rust_ir::WellKnownTrait::Clone) - } else if self.tcx.lang_items().drop_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_solve::rust_ir::WellKnownTrait::Drop) - } else if self.tcx.lang_items().fn_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_solve::rust_ir::WellKnownTrait::Fn) - } else if self.tcx.lang_items().fn_once_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce) - } else if self.tcx.lang_items().fn_mut_trait().map(|t| def_id == t).unwrap_or(false) { - Some(chalk_solve::rust_ir::WellKnownTrait::FnMut) - } else { - None - }; + let well_known = if self + .interner + .tcx + .lang_items() + .sized_trait() + .map(|t| def_id == t) + .unwrap_or(false) + { + Some(chalk_solve::rust_ir::WellKnownTrait::Sized) + } else if self.interner.tcx.lang_items().copy_trait().map(|t| def_id == t).unwrap_or(false) + { + Some(chalk_solve::rust_ir::WellKnownTrait::Copy) + } else if self.interner.tcx.lang_items().clone_trait().map(|t| def_id == t).unwrap_or(false) + { + Some(chalk_solve::rust_ir::WellKnownTrait::Clone) + } else if self.interner.tcx.lang_items().drop_trait().map(|t| def_id == t).unwrap_or(false) + { + Some(chalk_solve::rust_ir::WellKnownTrait::Drop) + } else if self.interner.tcx.lang_items().fn_trait().map(|t| def_id == t).unwrap_or(false) { + Some(chalk_solve::rust_ir::WellKnownTrait::Fn) + } else if self + .interner + .tcx + .lang_items() + .fn_once_trait() + .map(|t| def_id == t) + .unwrap_or(false) + { + Some(chalk_solve::rust_ir::WellKnownTrait::FnOnce) + } else if self + .interner + .tcx + .lang_items() + .fn_mut_trait() + .map(|t| def_id == t) + .unwrap_or(false) + { + Some(chalk_solve::rust_ir::WellKnownTrait::FnMut) + } else { + None + }; Arc::new(chalk_solve::rust_ir::TraitDatum { id: trait_id, binders: chalk_ir::Binders::new( @@ -138,7 +161,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t auto: trait_def.has_auto_impl, marker: trait_def.is_marker, upstream: !def_id.is_local(), - fundamental: self.tcx.has_attr(def_id, sym::fundamental), + fundamental: self.interner.tcx.has_attr(def_id, sym::fundamental), non_enumerable: true, coinductive: false, }, @@ -153,7 +176,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ) -> Arc>> { let adt_def = adt_id.0; - let bound_vars = bound_vars_for_item(self.tcx, adt_def.did); + let bound_vars = bound_vars_for_item(self.interner.tcx, adt_def.did); let binders = binders_for(&self.interner, bound_vars); let where_clauses = self.where_clauses_for(adt_def.did, bound_vars); @@ -165,16 +188,11 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fields: variant .fields .iter() - .map(|field| { - self.tcx - .type_of(field.did) - .subst(self.tcx, bound_vars) - .lower_into(&self.interner) - }) + .map(|field| field.ty(self.interner.tcx, bound_vars).lower_into(&self.interner)) .collect(), }) .collect(); - let struct_datum = Arc::new(chalk_solve::rust_ir::AdtDatum { + Arc::new(chalk_solve::rust_ir::AdtDatum { id: adt_id, binders: chalk_ir::Binders::new( binders, @@ -190,8 +208,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ty::AdtKind::Union => chalk_solve::rust_ir::AdtKind::Union, ty::AdtKind::Enum => chalk_solve::rust_ir::AdtKind::Enum, }, - }); - struct_datum + }) } fn adt_repr( @@ -210,27 +227,25 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t fn_def_id: chalk_ir::FnDefId>, ) -> Arc>> { let def_id = fn_def_id.0; - let bound_vars = bound_vars_for_item(self.tcx, def_id); + let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); let where_clauses = self.where_clauses_for(def_id, bound_vars); - let sig = self.tcx.fn_sig(def_id); - let inputs_and_output = sig.inputs_and_output(); - let inputs_and_output = inputs_and_output.subst(self.tcx, bound_vars); + let sig = self.interner.tcx.fn_sig(def_id); let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars( &self.interner, - self.tcx, - &inputs_and_output, + self.interner.tcx, + &sig.inputs_and_output().subst(self.interner.tcx, bound_vars), ); let argument_types = inputs_and_output[..inputs_and_output.len() - 1] .iter() - .map(|t| t.subst(self.tcx, &bound_vars).lower_into(&self.interner)) + .map(|t| t.subst(self.interner.tcx, &bound_vars).lower_into(&self.interner)) .collect(); let return_type = inputs_and_output[inputs_and_output.len() - 1] - .subst(self.tcx, &bound_vars) + .subst(self.interner.tcx, &bound_vars) .lower_into(&self.interner); let bound = chalk_solve::rust_ir::FnDefDatumBound { @@ -257,13 +272,13 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t impl_id: chalk_ir::ImplId>, ) -> Arc>> { let def_id = impl_id.0; - let bound_vars = bound_vars_for_item(self.tcx, def_id); + let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); - let trait_ref = self.tcx.impl_trait_ref(def_id).expect("not an impl"); - let trait_ref = trait_ref.subst(self.tcx, bound_vars); + let trait_ref = self.interner.tcx.impl_trait_ref(def_id).expect("not an impl"); + let trait_ref = trait_ref.subst(self.interner.tcx, bound_vars); let mut regions_substitutor = lowering::RegionsSubstitutor::new( - self.tcx, + self.interner.tcx, self.restatic_placeholder, self.reempty_placeholder, ); @@ -296,16 +311,16 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t // require us to be able to interconvert `Ty<'tcx>`, and we're // not there yet. - let all_impls = self.tcx.all_impls(def_id); + let all_impls = self.interner.tcx.all_impls(def_id); let matched_impls = all_impls.filter(|impl_def_id| { use chalk_ir::could_match::CouldMatch; - let trait_ref = self.tcx.impl_trait_ref(*impl_def_id).unwrap(); - let bound_vars = bound_vars_for_item(self.tcx, *impl_def_id); + let trait_ref = self.interner.tcx.impl_trait_ref(*impl_def_id).unwrap(); + let bound_vars = bound_vars_for_item(self.interner.tcx, *impl_def_id); let self_ty = trait_ref.self_ty(); - let self_ty = self_ty.subst(self.tcx, bound_vars); + let self_ty = self_ty.subst(self.interner.tcx, bound_vars); let mut regions_substitutor = lowering::RegionsSubstitutor::new( - self.tcx, + self.interner.tcx, self.restatic_placeholder, self.reempty_placeholder, ); @@ -326,9 +341,9 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ) -> bool { let trait_def_id = auto_trait_id.0; let adt_def = adt_id.0; - let all_impls = self.tcx.all_impls(trait_def_id); + let all_impls = self.interner.tcx.all_impls(trait_def_id); for impl_def_id in all_impls { - let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap(); + let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap(); let self_ty = trait_ref.self_ty(); match *self_ty.kind() { ty::Adt(impl_adt_def, _) => { @@ -347,7 +362,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t associated_ty_id: chalk_solve::rust_ir::AssociatedTyValueId>, ) -> Arc>> { let def_id = associated_ty_id.0; - let assoc_item = self.tcx.associated_item(def_id); + let assoc_item = self.interner.tcx.associated_item(def_id); let impl_id = match assoc_item.container { AssocItemContainer::TraitContainer(def_id) => def_id, _ => unimplemented!("Not possible??"), @@ -356,9 +371,9 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t AssocKind::Type => {} _ => unimplemented!("Not possible??"), } - let bound_vars = bound_vars_for_item(self.tcx, def_id); + let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); let binders = binders_for(&self.interner, bound_vars); - let ty = self.tcx.type_of(def_id); + let ty = self.interner.tcx.type_of(def_id); Arc::new(chalk_solve::rust_ir::AssociatedTyValue { impl_id: chalk_ir::ImplId(impl_id), @@ -385,7 +400,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t &self, opaque_ty_id: chalk_ir::OpaqueTyId>, ) -> Arc>> { - let bound_vars = bound_vars_for_item(self.tcx, opaque_ty_id.0); + let bound_vars = bound_vars_for_item(self.interner.tcx, opaque_ty_id.0); let binders = binders_for(&self.interner, bound_vars); let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars); @@ -395,7 +410,7 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t }; Arc::new(chalk_solve::rust_ir::OpaqueTyDatum { opaque_ty_id, - bound: chalk_ir::Binders::new(chalk_ir::VariableKinds::empty(&self.interner), value), + bound: chalk_ir::Binders::empty(&self.interner, value), }) } @@ -412,20 +427,20 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t ) -> Option>> { use chalk_solve::rust_ir::WellKnownTrait::*; let def_id = match well_known_trait { - Sized => self.tcx.lang_items().sized_trait(), - Copy => self.tcx.lang_items().copy_trait(), - Clone => self.tcx.lang_items().clone_trait(), - Drop => self.tcx.lang_items().drop_trait(), - Fn => self.tcx.lang_items().fn_trait(), - FnMut => self.tcx.lang_items().fn_mut_trait(), - FnOnce => self.tcx.lang_items().fn_once_trait(), - Unsize => self.tcx.lang_items().unsize_trait(), + Sized => self.interner.tcx.lang_items().sized_trait(), + Copy => self.interner.tcx.lang_items().copy_trait(), + Clone => self.interner.tcx.lang_items().clone_trait(), + Drop => self.interner.tcx.lang_items().drop_trait(), + Fn => self.interner.tcx.lang_items().fn_trait(), + FnMut => self.interner.tcx.lang_items().fn_mut_trait(), + FnOnce => self.interner.tcx.lang_items().fn_once_trait(), + Unsize => self.interner.tcx.lang_items().unsize_trait(), }; def_id.map(chalk_ir::TraitId) } fn is_object_safe(&self, trait_id: chalk_ir::TraitId>) -> bool { - self.tcx.is_object_safe(trait_id.0) + self.interner.tcx.is_object_safe(trait_id.0) } fn hidden_opaque_type( @@ -433,7 +448,10 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t _id: chalk_ir::OpaqueTyId>, ) -> chalk_ir::Ty> { // FIXME(chalk): actually get hidden ty - self.tcx.mk_ty(ty::Tuple(self.tcx.intern_substs(&[]))).lower_into(&self.interner) + self.interner + .tcx + .mk_ty(ty::Tuple(self.interner.tcx.intern_substs(&[]))) + .lower_into(&self.interner) } fn closure_kind( diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index c2a3fa22dc8..a67bd492a39 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -880,10 +880,6 @@ impl<'a, 'tcx> TypeFolder<'tcx> for NamedBoundVarSubstitutor<'a, 'tcx> { result } - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - t.super_fold_with(self) - } - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { match r { ty::ReLateBound(index, br) if *index == self.binder_index => match br { @@ -914,18 +910,18 @@ crate struct ParamsSubstitutor<'tcx> { tcx: TyCtxt<'tcx>, binder_index: ty::DebruijnIndex, list: Vec, - next_ty_placehoder: usize, + next_ty_placeholder: usize, crate params: rustc_data_structures::fx::FxHashMap, crate named_regions: BTreeMap, } impl<'tcx> ParamsSubstitutor<'tcx> { - crate fn new(tcx: TyCtxt<'tcx>, next_ty_placehoder: usize) -> Self { + crate fn new(tcx: TyCtxt<'tcx>, next_ty_placeholder: usize) -> Self { ParamsSubstitutor { tcx, binder_index: ty::INNERMOST, list: vec![], - next_ty_placehoder, + next_ty_placeholder, params: rustc_data_structures::fx::FxHashMap::default(), named_regions: BTreeMap::default(), } @@ -957,7 +953,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { })), None => { self.list.push(param); - let idx = self.list.len() - 1 + self.next_ty_placehoder; + let idx = self.list.len() - 1 + self.next_ty_placeholder; self.params.insert(idx, param); self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::from_usize(0), @@ -997,7 +993,7 @@ impl<'tcx> TypeFolder<'tcx> for ParamsSubstitutor<'tcx> { /// Used to collect `Placeholder`s. crate struct PlaceholdersCollector { universe_index: ty::UniverseIndex, - crate next_ty_placehoder: usize, + crate next_ty_placeholder: usize, crate next_anon_region_placeholder: u32, } @@ -1005,21 +1001,17 @@ impl PlaceholdersCollector { crate fn new() -> Self { PlaceholdersCollector { universe_index: ty::UniverseIndex::ROOT, - next_ty_placehoder: 0, + next_ty_placeholder: 0, next_anon_region_placeholder: 0, } } } impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { - fn visit_binder>(&mut self, t: &Binder) -> bool { - t.super_visit_with(self) - } - fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { match t.kind { ty::Placeholder(p) if p.universe == self.universe_index => { - self.next_ty_placehoder = self.next_ty_placehoder.max(p.name.as_usize() + 1); + self.next_ty_placeholder = self.next_ty_placeholder.max(p.name.as_usize() + 1); } _ => (), @@ -1065,14 +1057,6 @@ impl<'tcx> TypeFolder<'tcx> for RegionsSubstitutor<'tcx> { self.tcx } - fn fold_binder>(&mut self, t: &Binder) -> Binder { - t.super_fold_with(self) - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - t.super_fold_with(self) - } - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { match r { ty::ReStatic => self.restatic_placeholder, diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs index a8e5bae0fc4..c0d4a5d0e7e 100644 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ b/compiler/rustc_traits/src/chalk/mod.rs @@ -53,8 +53,9 @@ crate fn evaluate_goal<'tcx>( })); let mut params_substitutor = - ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placehoder); + ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder); let obligation = obligation.fold_with(&mut params_substitutor); + // FIXME(chalk): we really should be substituting these back in the solution let _params: FxHashMap = params_substitutor.params; let mut regions_substitutor = @@ -63,7 +64,7 @@ crate fn evaluate_goal<'tcx>( let max_universe = obligation.max_universe.index(); - let _lowered_goal: chalk_ir::UCanonical< + let lowered_goal: chalk_ir::UCanonical< chalk_ir::InEnvironment>>, > = chalk_ir::UCanonical { canonical: chalk_ir::Canonical { @@ -101,17 +102,17 @@ crate fn evaluate_goal<'tcx>( use chalk_solve::Solver; let mut solver = chalk_engine::solve::SLGSolver::new(32, None); - let db = ChalkRustIrDatabase { tcx, interner, restatic_placeholder, reempty_placeholder }; - let solution = chalk_solve::logging::with_tracing_logs(|| solver.solve(&db, &_lowered_goal)); + let db = ChalkRustIrDatabase { interner, restatic_placeholder, reempty_placeholder }; + let solution = chalk_solve::logging::with_tracing_logs(|| solver.solve(&db, &lowered_goal)); // Ideally, the code to convert *back* to rustc types would live close to // the code to convert *from* rustc types. Right now though, we don't // really need this and so it's really minimal. // Right now, we also treat a `Unique` solution the same as // `Ambig(Definite)`. This really isn't right. - let make_solution = |_subst: chalk_ir::Substitution<_>| { + let make_solution = |subst: chalk_ir::Substitution<_>| { let mut var_values: IndexVec> = IndexVec::new(); - _subst.as_slice(&interner).iter().for_each(|p| { + subst.as_slice(&interner).iter().for_each(|p| { var_values.push(p.lower_into(&interner)); }); let sol = Canonical { @@ -128,13 +129,13 @@ crate fn evaluate_goal<'tcx>( }; solution .map(|s| match s { - Solution::Unique(_subst) => { + Solution::Unique(subst) => { // FIXME(chalk): handle constraints - make_solution(_subst.value.subst) + make_solution(subst.value.subst) } - Solution::Ambig(_guidance) => { - match _guidance { - chalk_solve::Guidance::Definite(_subst) => make_solution(_subst.value), + Solution::Ambig(guidance) => { + match guidance { + chalk_solve::Guidance::Definite(subst) => make_solution(subst.value), chalk_solve::Guidance::Suggested(_) => unimplemented!(), chalk_solve::Guidance::Unknown => { // chalk_fulfill doesn't use the var_values here, so From 3a9a4e8b2d027f2f93e20fb3dee2834664dad299 Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Fri, 4 Sep 2020 01:51:57 -0400 Subject: [PATCH 4/5] Bless changed test output --- src/test/ui/chalkify/type_wf.stderr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/ui/chalkify/type_wf.stderr b/src/test/ui/chalkify/type_wf.stderr index 71009f1e97d..3cd60369454 100644 --- a/src/test/ui/chalkify/type_wf.stderr +++ b/src/test/ui/chalkify/type_wf.stderr @@ -8,8 +8,8 @@ LL | let s = S { | ^ the trait `Foo` is not implemented for `{float}` | = help: the following implementations were found: + as Foo> - as Foo> error: aborting due to previous error From 0aa215305a19fb3bab31b31898ee031cc3e10d7c Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Fri, 4 Sep 2020 19:17:57 -0400 Subject: [PATCH 5/5] kind -> kind() --- compiler/rustc_traits/src/chalk/lowering.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index a67bd492a39..e89a51a8176 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -1009,7 +1009,7 @@ impl PlaceholdersCollector { impl<'tcx> TypeVisitor<'tcx> for PlaceholdersCollector { fn visit_ty(&mut self, t: Ty<'tcx>) -> bool { - match t.kind { + match t.kind() { ty::Placeholder(p) if p.universe == self.universe_index => { self.next_ty_placeholder = self.next_ty_placeholder.max(p.name.as_usize() + 1); }