From 810fbf086d30521617faf8cdb3b6f175c6809766 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Jul 2023 15:19:08 +0000 Subject: [PATCH 1/3] Remove chalk from the compiler --- Cargo.lock | 75 - compiler/rustc_interface/src/tests.rs | 2 +- compiler/rustc_middle/Cargo.toml | 1 - compiler/rustc_middle/src/query/erase.rs | 1 - compiler/rustc_middle/src/query/mod.rs | 13 +- compiler/rustc_middle/src/traits/chalk.rs | 396 ------ compiler/rustc_middle/src/traits/mod.rs | 5 - compiler/rustc_session/src/config.rs | 2 - compiler/rustc_session/src/options.rs | 3 +- .../src/traits/chalk_fulfill.rs | 149 -- .../src/traits/engine.rs | 3 +- .../src/traits/error_reporting/mod.rs | 2 +- .../rustc_trait_selection/src/traits/mod.rs | 3 - .../src/traits/select/confirmation.rs | 12 +- compiler/rustc_traits/Cargo.toml | 3 - compiler/rustc_traits/src/chalk/db.rs | 796 ----------- compiler/rustc_traits/src/chalk/lowering.rs | 1234 ----------------- compiler/rustc_traits/src/chalk/mod.rs | 169 --- compiler/rustc_traits/src/lib.rs | 5 +- compiler/rustc_ty_utils/src/ty.rs | 118 +- src/tools/tidy/src/deps.rs | 2 - src/tools/tidy/src/ui_tests.rs | 2 +- tests/ui/chalkify/arithmetic.rs | 20 - tests/ui/chalkify/assert.rs | 6 - tests/ui/chalkify/basic.rs | 12 - tests/ui/chalkify/bugs/async.rs | 25 - tests/ui/chalkify/bugs/async.stderr | 22 - tests/ui/chalkify/builtin-copy-clone.rs | 45 - tests/ui/chalkify/chalk_initial_program.rs | 16 - .../ui/chalkify/chalk_initial_program.stderr | 18 - tests/ui/chalkify/closure.rs | 38 - tests/ui/chalkify/closure.stderr | 22 - tests/ui/chalkify/generic_impls.rs | 18 - tests/ui/chalkify/generic_impls.stderr | 29 - tests/ui/chalkify/impl_wf.rs | 26 - tests/ui/chalkify/impl_wf.stderr | 29 - tests/ui/chalkify/impl_wf_2.rs | 33 - tests/ui/chalkify/impl_wf_2.stderr | 16 - tests/ui/chalkify/inherent_impl.rs | 42 - tests/ui/chalkify/inherent_impl_min.rs | 27 - tests/ui/chalkify/lower_env1.rs | 14 - tests/ui/chalkify/lower_env2.rs | 16 - tests/ui/chalkify/lower_env3.rs | 16 - tests/ui/chalkify/lower_impl.rs | 17 - tests/ui/chalkify/lower_struct.rs | 8 - tests/ui/chalkify/lower_trait.rs | 11 - tests/ui/chalkify/lower_trait_higher_rank.rs | 9 - tests/ui/chalkify/lower_trait_where_clause.rs | 16 - tests/ui/chalkify/println.rs | 6 - tests/ui/chalkify/projection.rs | 25 - .../recursive_where_clause_on_type.rs | 30 - .../recursive_where_clause_on_type.stderr | 14 - tests/ui/chalkify/super_trait.rs | 19 - tests/ui/chalkify/trait-objects.rs | 12 - tests/ui/chalkify/trait_implied_bound.rs | 18 - tests/ui/chalkify/type_implied_bound.rs | 29 - tests/ui/chalkify/type_inference.rs | 28 - tests/ui/chalkify/type_inference.stderr | 20 - tests/ui/chalkify/type_wf.rs | 25 - tests/ui/chalkify/type_wf.stderr | 16 - tests/ui/impl-trait/issue-55872-3.stderr | 6 +- 61 files changed, 16 insertions(+), 3779 deletions(-) delete mode 100644 compiler/rustc_middle/src/traits/chalk.rs delete mode 100644 compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs delete mode 100644 compiler/rustc_traits/src/chalk/db.rs delete mode 100644 compiler/rustc_traits/src/chalk/lowering.rs delete mode 100644 compiler/rustc_traits/src/chalk/mod.rs delete mode 100644 tests/ui/chalkify/arithmetic.rs delete mode 100644 tests/ui/chalkify/assert.rs delete mode 100644 tests/ui/chalkify/basic.rs delete mode 100644 tests/ui/chalkify/bugs/async.rs delete mode 100644 tests/ui/chalkify/bugs/async.stderr delete mode 100644 tests/ui/chalkify/builtin-copy-clone.rs delete mode 100644 tests/ui/chalkify/chalk_initial_program.rs delete mode 100644 tests/ui/chalkify/chalk_initial_program.stderr delete mode 100644 tests/ui/chalkify/closure.rs delete mode 100644 tests/ui/chalkify/closure.stderr delete mode 100644 tests/ui/chalkify/generic_impls.rs delete mode 100644 tests/ui/chalkify/generic_impls.stderr delete mode 100644 tests/ui/chalkify/impl_wf.rs delete mode 100644 tests/ui/chalkify/impl_wf.stderr delete mode 100644 tests/ui/chalkify/impl_wf_2.rs delete mode 100644 tests/ui/chalkify/impl_wf_2.stderr delete mode 100644 tests/ui/chalkify/inherent_impl.rs delete mode 100644 tests/ui/chalkify/inherent_impl_min.rs delete mode 100644 tests/ui/chalkify/lower_env1.rs delete mode 100644 tests/ui/chalkify/lower_env2.rs delete mode 100644 tests/ui/chalkify/lower_env3.rs delete mode 100644 tests/ui/chalkify/lower_impl.rs delete mode 100644 tests/ui/chalkify/lower_struct.rs delete mode 100644 tests/ui/chalkify/lower_trait.rs delete mode 100644 tests/ui/chalkify/lower_trait_higher_rank.rs delete mode 100644 tests/ui/chalkify/lower_trait_where_clause.rs delete mode 100644 tests/ui/chalkify/println.rs delete mode 100644 tests/ui/chalkify/projection.rs delete mode 100644 tests/ui/chalkify/recursive_where_clause_on_type.rs delete mode 100644 tests/ui/chalkify/recursive_where_clause_on_type.stderr delete mode 100644 tests/ui/chalkify/super_trait.rs delete mode 100644 tests/ui/chalkify/trait-objects.rs delete mode 100644 tests/ui/chalkify/trait_implied_bound.rs delete mode 100644 tests/ui/chalkify/type_implied_bound.rs delete mode 100644 tests/ui/chalkify/type_inference.rs delete mode 100644 tests/ui/chalkify/type_inference.stderr delete mode 100644 tests/ui/chalkify/type_wf.rs delete mode 100644 tests/ui/chalkify/type_wf.stderr diff --git a/Cargo.lock b/Cargo.lock index 53a880e5b9f..ed164f64f6f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -433,60 +433,6 @@ dependencies = [ "rustc-std-workspace-core", ] -[[package]] -name = "chalk-derive" -version = "0.92.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff5053a8a42dbff5279a82423946fc56dc1253b76cf211b2b3c14b3aad4e1281" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.8", - "synstructure 0.13.0", -] - -[[package]] -name = "chalk-engine" -version = "0.92.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d0e18f29b8b0f4dcf7d31fe00c884af67719699e381e8dcc9d9624b1621c60" -dependencies = [ - "chalk-derive", - "chalk-ir", - "chalk-solve", - "rustc-hash", - "tracing", -] - -[[package]] -name = "chalk-ir" -version = "0.92.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a56de2146a8ed0fcd54f4bd50db852f1de4eac9e1efe568494f106c21b77d2a" -dependencies = [ - "bitflags 1.3.2", - "chalk-derive", - "lazy_static", -] - -[[package]] -name = "chalk-solve" -version = "0.92.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b392e02b4c81ec76d3748da839fc70a5539b83d27c9030668463d34d5110b860" -dependencies = [ - "chalk-derive", - "chalk-ir", - "ena", - "indexmap 1.9.3", - "itertools", - "petgraph", - "rustc-hash", - "tracing", - "tracing-subscriber", - "tracing-tree", -] - [[package]] name = "chrono" version = "0.4.26" @@ -1168,12 +1114,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "fixedbitset" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" - [[package]] name = "flate2" version = "1.0.26" @@ -2466,16 +2406,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "petgraph" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7" -dependencies = [ - "fixedbitset", - "indexmap 1.9.3", -] - [[package]] name = "phf" version = "0.10.1" @@ -3675,7 +3605,6 @@ name = "rustc_middle" version = "0.0.0" dependencies = [ "bitflags 1.3.2", - "chalk-ir", "derive_more", "either", "field-offset", @@ -4102,9 +4031,6 @@ dependencies = [ name = "rustc_traits" version = "0.0.0" dependencies = [ - "chalk-engine", - "chalk-ir", - "chalk-solve", "rustc_ast", "rustc_data_structures", "rustc_hir", @@ -5033,7 +4959,6 @@ dependencies = [ "thread_local", "tracing", "tracing-core", - "tracing-log", ] [[package]] diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index 0f5dba1df14..09141afd137 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -841,7 +841,7 @@ fn test_unstable_options_tracking_hash() { tracked!(thir_unsafeck, true); tracked!(tiny_const_eval_limit, true); tracked!(tls_model, Some(TlsModel::GeneralDynamic)); - tracked!(trait_solver, TraitSolver::Chalk); + tracked!(trait_solver, TraitSolver::NextCoherence); tracked!(translate_remapped_path_to_local_path, false); tracked!(trap_unreachable, Some(false)); tracked!(treat_err_as_bug, NonZeroUsize::new(1)); diff --git a/compiler/rustc_middle/Cargo.toml b/compiler/rustc_middle/Cargo.toml index 07ab3ba4e8a..4c238308fe8 100644 --- a/compiler/rustc_middle/Cargo.toml +++ b/compiler/rustc_middle/Cargo.toml @@ -7,7 +7,6 @@ edition = "2021" [dependencies] bitflags = "1.2.1" -chalk-ir = "0.92.0" derive_more = "0.99.17" either = "1.5.0" gsgdt = "0.1.2" diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs index e8f4fca147b..2c481745d98 100644 --- a/compiler/rustc_middle/src/query/erase.rs +++ b/compiler/rustc_middle/src/query/erase.rs @@ -315,7 +315,6 @@ tcx_lifetime! { rustc_middle::mir::interpret::ConstValue, rustc_middle::mir::interpret::GlobalId, rustc_middle::mir::interpret::LitToConstInput, - rustc_middle::traits::ChalkEnvironmentAndGoal, rustc_middle::traits::query::MethodAutoderefStepsResult, rustc_middle::traits::query::type_op::AscribeUserType, rustc_middle::traits::query::type_op::Eq, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index a8cdf8286fe..6f942e0bc86 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -39,8 +39,8 @@ use crate::traits::query::{ }; use crate::traits::specialization_graph; use crate::traits::{ - CanonicalChalkEnvironmentAndGoal, CodegenObligationError, EvaluationResult, ImplSource, - ObjectSafetyViolation, ObligationCause, OverflowError, WellFormedLoc, + CodegenObligationError, EvaluationResult, ImplSource, ObjectSafetyViolation, ObligationCause, + OverflowError, WellFormedLoc, }; use crate::ty::fast_reject::SimplifiedType; use crate::ty::layout::ValidityRequirement; @@ -1971,15 +1971,6 @@ rustc_queries! { desc { "evaluating trait selection obligation `{}`", goal.value.value } } - query evaluate_goal( - goal: CanonicalChalkEnvironmentAndGoal<'tcx> - ) -> Result< - &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, ()>>, - NoSolution - > { - desc { "evaluating trait selection obligation `{}`", goal.value } - } - /// Do not call this query directly: part of the `Eq` type-op query type_op_ascribe_user_type( goal: CanonicalTypeOpAscribeUserTypeGoal<'tcx> diff --git a/compiler/rustc_middle/src/traits/chalk.rs b/compiler/rustc_middle/src/traits/chalk.rs deleted file mode 100644 index 6e3d2d91ae9..00000000000 --- a/compiler/rustc_middle/src/traits/chalk.rs +++ /dev/null @@ -1,396 +0,0 @@ -//! Types required for Chalk-related queries -//! -//! The primary purpose of this file is defining an implementation for the -//! `chalk_ir::interner::Interner` trait. The primary purpose of this trait, as -//! its name suggest, is to provide an abstraction boundary for creating -//! interned Chalk types. - -use rustc_middle::ty::{self, AdtDef, TyCtxt}; - -use rustc_hir::def_id::DefId; -use rustc_target::spec::abi::Abi; - -use std::cmp::Ordering; -use std::fmt; -use std::hash::{Hash, Hasher}; - -#[derive(Copy, Clone)] -pub struct RustInterner<'tcx> { - pub tcx: TyCtxt<'tcx>, -} - -/// We don't ever actually need this. It's only required for derives. -impl<'tcx> Hash for RustInterner<'tcx> { - fn hash(&self, _state: &mut H) {} -} - -/// We don't ever actually need this. It's only required for derives. -impl<'tcx> Ord for RustInterner<'tcx> { - fn cmp(&self, _other: &Self) -> Ordering { - Ordering::Equal - } -} - -/// We don't ever actually need this. It's only required for derives. -impl<'tcx> PartialOrd for RustInterner<'tcx> { - fn partial_cmp(&self, _other: &Self) -> Option { - None - } -} - -/// We don't ever actually need this. It's only required for derives. -impl<'tcx> PartialEq for RustInterner<'tcx> { - fn eq(&self, _other: &Self) -> bool { - false - } -} - -/// We don't ever actually need this. It's only required for derives. -impl<'tcx> Eq for RustInterner<'tcx> {} - -impl fmt::Debug for RustInterner<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "RustInterner") - } -} - -// Right now, there is no interning at all. I was running into problems with -// adding interning in `ty/context.rs` for Chalk types with -// `parallel-compiler = true`. -jackh726 -impl<'tcx> chalk_ir::interner::Interner for RustInterner<'tcx> { - type InternedType = Box>; - type InternedLifetime = Box>; - type InternedConst = Box>; - type InternedConcreteConst = ty::ValTree<'tcx>; - type InternedGenericArg = Box>; - type InternedGoal = Box>; - type InternedGoals = Vec>; - type InternedSubstitution = Vec>; - type InternedProgramClause = Box>; - type InternedProgramClauses = Vec>; - type InternedQuantifiedWhereClauses = Vec>; - type InternedVariableKinds = Vec>; - type InternedCanonicalVarKinds = Vec>; - type InternedVariances = Vec; - type InternedConstraints = Vec>>; - type DefId = DefId; - type InternedAdtId = AdtDef<'tcx>; - type Identifier = (); - type FnAbi = Abi; - - fn debug_program_clause_implication( - pci: &chalk_ir::ProgramClauseImplication, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - let mut write = || { - write!(fmt, "{:?}", pci.consequence)?; - - let conditions = pci.conditions.interned(); - let constraints = pci.constraints.interned(); - - let conds = conditions.len(); - let consts = constraints.len(); - if conds == 0 && consts == 0 { - return Ok(()); - } - - write!(fmt, " :- ")?; - - if conds != 0 { - for cond in &conditions[..conds - 1] { - write!(fmt, "{:?}, ", cond)?; - } - write!(fmt, "{:?}", conditions[conds - 1])?; - } - - if conds != 0 && consts != 0 { - write!(fmt, " ; ")?; - } - - if consts != 0 { - for constraint in &constraints[..consts - 1] { - write!(fmt, "{:?}, ", constraint)?; - } - write!(fmt, "{:?}", constraints[consts - 1])?; - } - - Ok(()) - }; - Some(write()) - } - - fn debug_substitution( - substitution: &chalk_ir::Substitution, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - Some(write!(fmt, "{:?}", substitution.interned())) - } - - fn debug_separator_trait_ref( - separator_trait_ref: &chalk_ir::SeparatorTraitRef<'_, Self>, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - let substitution = &separator_trait_ref.trait_ref.substitution; - let parameters = substitution.interned(); - Some(write!( - fmt, - "{:?}{}{:?}{:?}", - parameters[0], - separator_trait_ref.separator, - separator_trait_ref.trait_ref.trait_id, - chalk_ir::debug::Angle(¶meters[1..]) - )) - } - - fn debug_quantified_where_clauses( - clauses: &chalk_ir::QuantifiedWhereClauses, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - Some(write!(fmt, "{:?}", clauses.interned())) - } - - fn debug_ty(ty: &chalk_ir::Ty, fmt: &mut fmt::Formatter<'_>) -> Option { - match &ty.interned().kind { - chalk_ir::TyKind::Ref(chalk_ir::Mutability::Not, lifetime, ty) => { - Some(write!(fmt, "(&{:?} {:?})", lifetime, ty)) - } - chalk_ir::TyKind::Ref(chalk_ir::Mutability::Mut, lifetime, ty) => { - Some(write!(fmt, "(&{:?} mut {:?})", lifetime, ty)) - } - chalk_ir::TyKind::Array(ty, len) => Some(write!(fmt, "[{:?}; {:?}]", ty, len)), - chalk_ir::TyKind::Slice(ty) => Some(write!(fmt, "[{:?}]", ty)), - chalk_ir::TyKind::Tuple(len, substs) => Some( - try { - write!(fmt, "(")?; - for (idx, substitution) in substs.interned().iter().enumerate() { - if idx == *len && *len != 1 { - // Don't add a trailing comma if the tuple has more than one element - write!(fmt, "{:?}", substitution)?; - } else { - write!(fmt, "{:?},", substitution)?; - } - } - write!(fmt, ")")?; - }, - ), - _ => None, - } - } - - fn debug_alias( - alias_ty: &chalk_ir::AliasTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - match alias_ty { - chalk_ir::AliasTy::Projection(projection_ty) => { - Self::debug_projection_ty(projection_ty, fmt) - } - chalk_ir::AliasTy::Opaque(opaque_ty) => Self::debug_opaque_ty(opaque_ty, fmt), - } - } - - fn debug_projection_ty( - projection_ty: &chalk_ir::ProjectionTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - Some(write!( - fmt, - "projection: {:?} {:?}", - projection_ty.associated_ty_id, projection_ty.substitution, - )) - } - - fn debug_opaque_ty( - opaque_ty: &chalk_ir::OpaqueTy, - fmt: &mut fmt::Formatter<'_>, - ) -> Option { - Some(write!(fmt, "{:?}", opaque_ty.opaque_ty_id)) - } - - fn intern_ty(self, ty: chalk_ir::TyKind) -> Self::InternedType { - let flags = ty.compute_flags(self); - Box::new(chalk_ir::TyData { kind: ty, flags: flags }) - } - - fn ty_data(self, ty: &Self::InternedType) -> &chalk_ir::TyData { - ty - } - - fn intern_lifetime(self, lifetime: chalk_ir::LifetimeData) -> Self::InternedLifetime { - Box::new(lifetime) - } - - fn lifetime_data(self, lifetime: &Self::InternedLifetime) -> &chalk_ir::LifetimeData { - &lifetime - } - - fn intern_const(self, constant: chalk_ir::ConstData) -> Self::InternedConst { - Box::new(constant) - } - - fn const_data(self, constant: &Self::InternedConst) -> &chalk_ir::ConstData { - &constant - } - - fn const_eq( - self, - _ty: &Self::InternedType, - c1: &Self::InternedConcreteConst, - c2: &Self::InternedConcreteConst, - ) -> bool { - c1 == c2 - } - - fn intern_generic_arg(self, data: chalk_ir::GenericArgData) -> Self::InternedGenericArg { - Box::new(data) - } - - fn generic_arg_data(self, data: &Self::InternedGenericArg) -> &chalk_ir::GenericArgData { - &data - } - - fn intern_goal(self, goal: chalk_ir::GoalData) -> Self::InternedGoal { - Box::new(goal) - } - - fn goal_data(self, goal: &Self::InternedGoal) -> &chalk_ir::GoalData { - &goal - } - - fn intern_goals( - self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn goals_data(self, goals: &Self::InternedGoals) -> &[chalk_ir::Goal] { - goals - } - - fn intern_substitution( - self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn substitution_data( - self, - substitution: &Self::InternedSubstitution, - ) -> &[chalk_ir::GenericArg] { - substitution - } - - fn intern_program_clause( - self, - data: chalk_ir::ProgramClauseData, - ) -> Self::InternedProgramClause { - Box::new(data) - } - - fn program_clause_data( - self, - clause: &Self::InternedProgramClause, - ) -> &chalk_ir::ProgramClauseData { - &clause - } - - fn intern_program_clauses( - self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn program_clauses_data( - self, - clauses: &Self::InternedProgramClauses, - ) -> &[chalk_ir::ProgramClause] { - clauses - } - - fn intern_quantified_where_clauses( - self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn quantified_where_clauses_data( - self, - clauses: &Self::InternedQuantifiedWhereClauses, - ) -> &[chalk_ir::QuantifiedWhereClause] { - clauses - } - - fn intern_generic_arg_kinds( - self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn variable_kinds_data( - self, - parameter_kinds: &Self::InternedVariableKinds, - ) -> &[chalk_ir::VariableKind] { - parameter_kinds - } - - fn intern_canonical_var_kinds( - self, - data: impl IntoIterator, E>>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn canonical_var_kinds_data( - self, - canonical_var_kinds: &Self::InternedCanonicalVarKinds, - ) -> &[chalk_ir::CanonicalVarKind] { - canonical_var_kinds - } - - fn intern_constraints( - self, - data: impl IntoIterator>, E>>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn constraints_data( - self, - constraints: &Self::InternedConstraints, - ) -> &[chalk_ir::InEnvironment>] { - constraints - } - - fn intern_variances( - self, - data: impl IntoIterator>, - ) -> Result { - data.into_iter().collect::, _>>() - } - - fn variances_data(self, variances: &Self::InternedVariances) -> &[chalk_ir::Variance] { - variances - } -} - -impl<'tcx> chalk_ir::interner::HasInterner for RustInterner<'tcx> { - type Interner = Self; -} - -/// A chalk environment and goal. -#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug, HashStable, TypeFoldable, TypeVisitable)] -pub struct ChalkEnvironmentAndGoal<'tcx> { - pub environment: &'tcx ty::List>, - pub goal: ty::Predicate<'tcx>, -} - -impl<'tcx> fmt::Display for ChalkEnvironmentAndGoal<'tcx> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "environment: {:?}, goal: {}", self.environment, self.goal) - } -} diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index a333fbbb506..69d826bbe7a 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -2,7 +2,6 @@ //! //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html -mod chalk; pub mod query; pub mod select; pub mod solve; @@ -30,12 +29,8 @@ use std::hash::{Hash, Hasher}; pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache}; -pub type CanonicalChalkEnvironmentAndGoal<'tcx> = Canonical<'tcx, ChalkEnvironmentAndGoal<'tcx>>; - pub use self::ObligationCauseCode::*; -pub use self::chalk::{ChalkEnvironmentAndGoal, RustInterner as ChalkRustInterner}; - /// Depending on the stage of compilation, we want projection to be /// more or less conservative. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)] diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 2fe7a6f511b..43846e65bca 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -737,8 +737,6 @@ pub enum PrintRequest { pub enum TraitSolver { /// Classic trait solver in `rustc_trait_selection::traits::select` Classic, - /// Chalk trait solver - Chalk, /// Experimental trait solver in `rustc_trait_selection::solve` Next, /// Use the new trait solver during coherence diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 16a4c2a8b3d..05d3e71074a 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -386,7 +386,7 @@ mod desc { pub const parse_unpretty: &str = "`string` or `string=string`"; pub const parse_treat_err_as_bug: &str = "either no value or a number bigger than 0"; pub const parse_trait_solver: &str = - "one of the supported solver modes (`classic`, `chalk`, or `next`)"; + "one of the supported solver modes (`classic`, `next`, or `next-coherence`)"; pub const parse_lto: &str = "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted"; pub const parse_linker_plugin_lto: &str = @@ -983,7 +983,6 @@ mod parse { pub(crate) fn parse_trait_solver(slot: &mut TraitSolver, v: Option<&str>) -> bool { match v { Some("classic") => *slot = TraitSolver::Classic, - Some("chalk") => *slot = TraitSolver::Chalk, Some("next") => *slot = TraitSolver::Next, Some("next-coherence") => *slot = TraitSolver::NextCoherence, // default trait solver is subject to change.. diff --git a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs b/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs deleted file mode 100644 index 3ecae429c59..00000000000 --- a/compiler/rustc_trait_selection/src/traits/chalk_fulfill.rs +++ /dev/null @@ -1,149 +0,0 @@ -//! Defines a Chalk-based `TraitEngine` - -use crate::infer::canonical::OriginalQueryValues; -use crate::infer::InferCtxt; -use crate::traits::query::NoSolution; -use crate::traits::{ - ChalkEnvironmentAndGoal, FulfillmentError, FulfillmentErrorCode, PredicateObligation, - SelectionError, TraitEngine, -}; -use rustc_data_structures::fx::FxIndexSet; -use rustc_middle::ty::TypeVisitableExt; - -pub struct FulfillmentContext<'tcx> { - obligations: FxIndexSet>, - - /// The snapshot in which this context was created. Using the context - /// outside of this snapshot leads to subtle bugs if the snapshot - /// gets rolled back. Because of this we explicitly check that we only - /// use the context in exactly this snapshot. - usable_in_snapshot: usize, -} - -impl<'tcx> FulfillmentContext<'tcx> { - pub(super) fn new(infcx: &InferCtxt<'tcx>) -> Self { - FulfillmentContext { - obligations: FxIndexSet::default(), - usable_in_snapshot: infcx.num_open_snapshots(), - } - } -} - -impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> { - fn register_predicate_obligation( - &mut self, - infcx: &InferCtxt<'tcx>, - obligation: PredicateObligation<'tcx>, - ) { - assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); - let obligation = infcx.resolve_vars_if_possible(obligation); - - self.obligations.insert(obligation); - } - - fn collect_remaining_errors( - &mut self, - _infcx: &InferCtxt<'tcx>, - ) -> Vec> { - // any remaining obligations are errors - self.obligations - .iter() - .map(|obligation| FulfillmentError { - obligation: obligation.clone(), - code: FulfillmentErrorCode::CodeAmbiguity { overflow: false }, - // FIXME - does Chalk have a notation of 'root obligation'? - // This is just for diagnostics, so it's okay if this is wrong - root_obligation: obligation.clone(), - }) - .collect() - } - - fn select_where_possible(&mut self, infcx: &InferCtxt<'tcx>) -> Vec> { - assert_eq!(self.usable_in_snapshot, infcx.num_open_snapshots()); - - let mut errors = Vec::new(); - let mut next_round = FxIndexSet::default(); - let mut making_progress; - - loop { - making_progress = false; - - // We iterate over all obligations, and record if we are able - // to unambiguously prove at least one obligation. - for obligation in self.obligations.drain(..) { - let obligation = infcx.resolve_vars_if_possible(obligation); - let environment = obligation.param_env.caller_bounds(); - let goal = ChalkEnvironmentAndGoal { environment, goal: obligation.predicate }; - let mut orig_values = OriginalQueryValues::default(); - if goal.references_error() { - continue; - } - - let canonical_goal = - infcx.canonicalize_query_preserving_universes(goal, &mut orig_values); - - match infcx.tcx.evaluate_goal(canonical_goal) { - Ok(response) => { - if response.is_proven() { - making_progress = true; - - match infcx.instantiate_query_response_and_region_obligations( - &obligation.cause, - obligation.param_env, - &orig_values, - &response, - ) { - Ok(infer_ok) => { - next_round.extend(infer_ok.obligations.into_iter().map( - |obligation| infcx.resolve_vars_if_possible(obligation), - )) - } - - Err(_err) => errors.push(FulfillmentError { - obligation: obligation.clone(), - code: FulfillmentErrorCode::CodeSelectionError( - SelectionError::Unimplemented, - ), - // FIXME - does Chalk have a notation of 'root obligation'? - // This is just for diagnostics, so it's okay if this is wrong - root_obligation: obligation, - }), - } - } else { - // Ambiguous: retry at next round. - next_round.insert(obligation); - } - } - - Err(NoSolution) => errors.push(FulfillmentError { - obligation: obligation.clone(), - code: FulfillmentErrorCode::CodeSelectionError( - SelectionError::Unimplemented, - ), - // FIXME - does Chalk have a notation of 'root obligation'? - // This is just for diagnostics, so it's okay if this is wrong - root_obligation: obligation, - }), - } - } - next_round = std::mem::replace(&mut self.obligations, next_round); - - if !making_progress { - break; - } - } - - errors - } - - fn drain_unstalled_obligations( - &mut self, - _: &InferCtxt<'tcx>, - ) -> Vec> { - unimplemented!() - } - - fn pending_obligations(&self) -> Vec> { - self.obligations.iter().cloned().collect() - } -} diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index 19dd4ce06b0..61f693e1bd1 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -1,8 +1,8 @@ use std::cell::RefCell; use std::fmt::Debug; +use super::FulfillmentContext; use super::TraitEngine; -use super::{ChalkFulfillmentContext, FulfillmentContext}; use crate::solve::FulfillmentCtxt as NextFulfillmentCtxt; use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::NormalizeExt; @@ -39,7 +39,6 @@ impl<'tcx> TraitEngineExt<'tcx> for dyn TraitEngine<'tcx> { (TraitSolver::Next | TraitSolver::NextCoherence, true) => { Box::new(NextFulfillmentCtxt::new(infcx)) } - (TraitSolver::Chalk, false) => Box::new(ChalkFulfillmentContext::new(infcx)), _ => bug!( "incompatible combination of -Ztrait-solver flag ({:?}) and InferCtxt::next_trait_solver ({:?})", infcx.tcx.sess.opts.unstable_opts.trait_solver, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index f7670d51bdc..cddfb15869f 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1059,7 +1059,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { // (which may fail). span_bug!(span, "WF predicate not satisfied for {:?}", ty); } - TraitSolver::Chalk | TraitSolver::Next | TraitSolver::NextCoherence => { + TraitSolver::Next | TraitSolver::NextCoherence => { // FIXME: we'll need a better message which takes into account // which bounds actually failed to hold. self.tcx.sess.struct_span_err( diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 720998a51e0..e2ee347b639 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -3,7 +3,6 @@ //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/resolution.html pub mod auto_trait; -mod chalk_fulfill; pub(crate) mod coherence; pub mod const_evaluatable; mod engine; @@ -74,8 +73,6 @@ pub use self::util::{ pub use self::util::{expand_trait_aliases, TraitAliasExpander}; pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices}; -pub use self::chalk_fulfill::FulfillmentContext as ChalkFulfillmentContext; - pub use rustc_infer::traits::*; /// Whether to skip the leak check, as part of a future compatibility warning step. diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index cc6521f3b50..f45d348fa96 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -16,7 +16,6 @@ use rustc_middle::ty::{ self, Binder, GenericParamDefKind, InternalSubsts, SubstsRef, ToPolyTraitRef, ToPredicate, TraitPredicate, TraitRef, Ty, TyCtxt, TypeVisitableExt, }; -use rustc_session::config::TraitSolver; use rustc_span::def_id::DefId; use crate::traits::project::{normalize_with_depth, normalize_with_depth_to}; @@ -830,13 +829,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { debug!(?closure_def_id, ?trait_ref, ?nested, "confirm closure candidate obligations"); - // FIXME: Chalk - if self.tcx().sess.opts.unstable_opts.trait_solver != TraitSolver::Chalk { - nested.push(obligation.with( - self.tcx(), - ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)), - )); - } + nested.push(obligation.with( + self.tcx(), + ty::Binder::dummy(ty::PredicateKind::ClosureKind(closure_def_id, substs, kind)), + )); Ok(nested) } diff --git a/compiler/rustc_traits/Cargo.toml b/compiler/rustc_traits/Cargo.toml index 189f72d478e..37e00c0e4bc 100644 --- a/compiler/rustc_traits/Cargo.toml +++ b/compiler/rustc_traits/Cargo.toml @@ -11,9 +11,6 @@ rustc_hir = { path = "../rustc_hir" } rustc_ast = { path = "../rustc_ast" } rustc_span = { path = "../rustc_span" } rustc_target = { path = "../rustc_target" } -chalk-ir = "0.92.0" -chalk-engine = "0.92.0" -chalk-solve = "0.92.0" smallvec = { version = "1.8.1", 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 deleted file mode 100644 index 0435cd63e80..00000000000 --- a/compiler/rustc_traits/src/chalk/db.rs +++ /dev/null @@ -1,796 +0,0 @@ -//! Provides the `RustIrDatabase` implementation for `chalk-solve` -//! -//! The purpose of the `chalk_solve::RustIrDatabase` is to get data about -//! specific types, such as bounds, where clauses, or fields. This file contains -//! the minimal logic to assemble the types for `chalk-solve` by calling out to -//! either the `TyCtxt` (for information about types) or -//! `crate::chalk::lowering` (to lower rustc types into Chalk types). - -use rustc_middle::traits::ChalkRustInterner as RustInterner; -use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable}; -use rustc_middle::ty::{InternalSubsts, SubstsRef}; -use rustc_target::abi::{Integer, IntegerType}; - -use rustc_ast::ast; - -use rustc_hir::def_id::DefId; - -use rustc_span::symbol::sym; - -use std::fmt; -use std::sync::Arc; - -use crate::chalk::lowering::LowerInto; - -pub struct RustIrDatabase<'tcx> { - pub(crate) interner: RustInterner<'tcx>, -} - -impl fmt::Debug for RustIrDatabase<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "RustIrDatabase") - } -} - -impl<'tcx> RustIrDatabase<'tcx> { - fn where_clauses_for( - &self, - def_id: DefId, - bound_vars: SubstsRef<'tcx>, - ) -> Vec>> { - self.interner - .tcx - .predicates_defined_on(def_id) - .instantiate_own(self.interner.tcx, bound_vars) - .filter_map(|(wc, _)| LowerInto::lower_into(wc.as_predicate(), self.interner)) - .collect() - } - - fn bounds_for(&self, def_id: DefId, bound_vars: SubstsRef<'tcx>) -> Vec - where - ty::Predicate<'tcx>: LowerInto<'tcx, std::option::Option>, - { - self.interner - .tcx - .explicit_item_bounds(def_id) - .subst_iter_copied(self.interner.tcx, &bound_vars) - .filter_map(|(bound, _)| { - LowerInto::>::lower_into(bound.as_predicate(), self.interner) - }) - .collect() - } -} - -impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'tcx> { - fn interner(&self) -> RustInterner<'tcx> { - self.interner - } - - fn associated_ty_data( - &self, - assoc_type_id: chalk_ir::AssocTypeId>, - ) -> Arc>> { - let def_id = assoc_type_id.0; - let assoc_item = self.interner.tcx.associated_item(def_id); - let Some(trait_def_id) = assoc_item.trait_container(self.interner.tcx) else { - unimplemented!("Not possible??"); - }; - match assoc_item.kind { - AssocKind::Type => {} - _ => unimplemented!("Not possible??"), - } - 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 bounds = self.bounds_for(def_id, bound_vars); - - Arc::new(chalk_solve::rust_ir::AssociatedTyDatum { - trait_id: chalk_ir::TraitId(trait_def_id), - id: assoc_type_id, - name: (), - binders: chalk_ir::Binders::new( - binders, - chalk_solve::rust_ir::AssociatedTyDatumBound { bounds, where_clauses }, - ), - }) - } - - fn trait_datum( - &self, - trait_id: chalk_ir::TraitId>, - ) -> Arc>> { - use chalk_solve::rust_ir::WellKnownTrait::*; - - let def_id = trait_id.0; - let trait_def = self.interner.tcx.trait_def(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() - .filter(|i| i.kind == AssocKind::Type) - .map(|i| chalk_ir::AssocTypeId(i.def_id)) - .collect(); - - let lang_items = self.interner.tcx.lang_items(); - let well_known = if lang_items.sized_trait() == Some(def_id) { - Some(Sized) - } else if lang_items.copy_trait() == Some(def_id) { - Some(Copy) - } else if lang_items.clone_trait() == Some(def_id) { - Some(Clone) - } else if lang_items.drop_trait() == Some(def_id) { - Some(Drop) - } else if lang_items.fn_trait() == Some(def_id) { - Some(Fn) - } else if lang_items.fn_once_trait() == Some(def_id) { - Some(FnOnce) - } else if lang_items.fn_mut_trait() == Some(def_id) { - Some(FnMut) - } else if lang_items.unsize_trait() == Some(def_id) { - Some(Unsize) - } else if lang_items.unpin_trait() == Some(def_id) { - Some(Unpin) - } else if lang_items.coerce_unsized_trait() == Some(def_id) { - Some(CoerceUnsized) - } else if lang_items.dispatch_from_dyn_trait() == Some(def_id) { - Some(DispatchFromDyn) - } else if lang_items.tuple_trait() == Some(def_id) { - Some(Tuple) - } else { - None - }; - Arc::new(chalk_solve::rust_ir::TraitDatum { - id: trait_id, - binders: chalk_ir::Binders::new( - binders, - chalk_solve::rust_ir::TraitDatumBound { where_clauses }, - ), - flags: chalk_solve::rust_ir::TraitFlags { - auto: trait_def.has_auto_impl, - marker: trait_def.is_marker, - upstream: !def_id.is_local(), - fundamental: self.interner.tcx.has_attr(def_id, sym::fundamental), - non_enumerable: true, - coinductive: false, - }, - associated_ty_ids, - well_known, - }) - } - - fn adt_datum( - &self, - adt_id: chalk_ir::AdtId>, - ) -> Arc>> { - let adt_def = adt_id.0; - - 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); - - let variants: Vec<_> = adt_def - .variants() - .iter() - .map(|variant| chalk_solve::rust_ir::AdtVariantDatum { - fields: variant - .fields - .iter() - .map(|field| field.ty(self.interner.tcx, bound_vars).lower_into(self.interner)) - .collect(), - }) - .collect(); - Arc::new(chalk_solve::rust_ir::AdtDatum { - id: adt_id, - binders: chalk_ir::Binders::new( - binders, - 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, - }, - }) - } - - fn adt_repr( - &self, - adt_id: chalk_ir::AdtId>, - ) -> Arc>> { - let adt_def = adt_id.0; - let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)).intern(self.interner); - let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)).intern(self.interner); - Arc::new(chalk_solve::rust_ir::AdtRepr { - c: adt_def.repr().c(), - packed: adt_def.repr().packed(), - int: adt_def.repr().int.map(|i| match i { - IntegerType::Pointer(true) => int(chalk_ir::IntTy::Isize), - IntegerType::Pointer(false) => uint(chalk_ir::UintTy::Usize), - IntegerType::Fixed(i, true) => match i { - Integer::I8 => int(chalk_ir::IntTy::I8), - Integer::I16 => int(chalk_ir::IntTy::I16), - Integer::I32 => int(chalk_ir::IntTy::I32), - Integer::I64 => int(chalk_ir::IntTy::I64), - Integer::I128 => int(chalk_ir::IntTy::I128), - }, - IntegerType::Fixed(i, false) => match i { - Integer::I8 => uint(chalk_ir::UintTy::U8), - Integer::I16 => uint(chalk_ir::UintTy::U16), - Integer::I32 => uint(chalk_ir::UintTy::U32), - Integer::I64 => uint(chalk_ir::UintTy::U64), - Integer::I128 => uint(chalk_ir::UintTy::U128), - }, - }), - }) - } - - fn adt_size_align( - &self, - adt_id: chalk_ir::AdtId>, - ) -> Arc { - let tcx = self.interner.tcx; - let did = adt_id.0.did(); - - // Grab the ADT and the param we might need to calculate its layout - let param_env = tcx.param_env(did); - let adt_ty = tcx.type_of(did).subst_identity(); - - // The ADT is a 1-zst if it's a ZST and its alignment is 1. - // Mark the ADT as _not_ a 1-zst if there was a layout error. - let one_zst = if let Ok(layout) = tcx.layout_of(param_env.and(adt_ty)) { - layout.is_zst() && layout.align.abi.bytes() == 1 - } else { - false - }; - - Arc::new(chalk_solve::rust_ir::AdtSizeAlign::from_one_zst(one_zst)) - } - - fn fn_def_datum( - &self, - fn_def_id: chalk_ir::FnDefId>, - ) -> Arc>> { - let def_id = fn_def_id.0; - 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.interner.tcx.fn_sig(def_id); - let (inputs_and_output, iobinders, _) = crate::chalk::lowering::collect_bound_vars( - self.interner, - self.interner.tcx, - sig.map_bound(|s| s.inputs_and_output()).subst(self.interner.tcx, bound_vars), - ); - - let argument_types = inputs_and_output[..inputs_and_output.len() - 1] - .iter() - .map(|t| sig.rebind(*t).subst(self.interner.tcx, &bound_vars).lower_into(self.interner)) - .collect(); - - let return_type = sig - .rebind(inputs_and_output[inputs_and_output.len() - 1]) - .subst(self.interner.tcx, &bound_vars) - .lower_into(self.interner); - - let bound = chalk_solve::rust_ir::FnDefDatumBound { - inputs_and_output: chalk_ir::Binders::new( - iobinders, - chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type }, - ), - where_clauses, - }; - Arc::new(chalk_solve::rust_ir::FnDefDatum { - id: fn_def_id, - sig: sig.skip_binder().lower_into(self.interner), - binders: chalk_ir::Binders::new(binders, bound), - }) - } - - fn impl_datum( - &self, - impl_id: chalk_ir::ImplId>, - ) -> Arc>> { - let def_id = impl_id.0; - let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); - let binders = binders_for(self.interner, 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 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), - where_clauses, - }; - - let associated_ty_value_ids: Vec<_> = self - .interner - .tcx - .associated_items(def_id) - .in_definition_order() - .filter(|i| i.kind == AssocKind::Type) - .map(|i| chalk_solve::rust_ir::AssociatedTyValueId(i.def_id)) - .collect(); - - Arc::new(chalk_solve::rust_ir::ImplDatum { - polarity: self.interner.tcx.impl_polarity(def_id).lower_into(self.interner), - binders: chalk_ir::Binders::new(binders, value), - impl_type: chalk_solve::rust_ir::ImplType::Local, - associated_ty_value_ids, - }) - } - - fn impls_for_trait( - &self, - trait_id: chalk_ir::TraitId>, - parameters: &[chalk_ir::GenericArg>], - _binders: &chalk_ir::CanonicalVarKinds>, - ) -> Vec>> { - let def_id = trait_id.0; - - // FIXME(chalk): use TraitDef::for_each_relevant_impl, but that will - // require us to be able to interconvert `Ty<'tcx>`, and we're - // not there yet. - - 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.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.map_bound(|t| t.self_ty()); - let self_ty = self_ty.subst(self.interner.tcx, bound_vars); - let lowered_ty = self_ty.lower_into(self.interner); - - parameters[0].assert_ty_ref(self.interner).could_match( - self.interner, - self.unification_database(), - &lowered_ty, - ) - }); - - let impls = matched_impls.map(chalk_ir::ImplId).collect(); - impls - } - - fn impl_provided_for( - &self, - auto_trait_id: chalk_ir::TraitId>, - chalk_ty: &chalk_ir::TyKind>, - ) -> bool { - use chalk_ir::Scalar::*; - use chalk_ir::TyKind::*; - - let trait_def_id = auto_trait_id.0; - let all_impls = self.interner.tcx.all_impls(trait_def_id); - for impl_def_id in all_impls { - let trait_ref = self.interner.tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(); - let self_ty = trait_ref.self_ty(); - let provides = match (self_ty.kind(), chalk_ty) { - (&ty::Adt(impl_adt_def, ..), Adt(id, ..)) => impl_adt_def.did() == id.0.did(), - (_, AssociatedType(_ty_id, ..)) => { - // FIXME(chalk): See https://github.com/rust-lang/rust/pull/77152#discussion_r494484774 - false - } - (ty::Bool, Scalar(Bool)) => true, - (ty::Char, Scalar(Char)) => true, - (ty::Int(ty1), Scalar(Int(ty2))) => matches!( - (ty1, ty2), - (ty::IntTy::Isize, chalk_ir::IntTy::Isize) - | (ty::IntTy::I8, chalk_ir::IntTy::I8) - | (ty::IntTy::I16, chalk_ir::IntTy::I16) - | (ty::IntTy::I32, chalk_ir::IntTy::I32) - | (ty::IntTy::I64, chalk_ir::IntTy::I64) - | (ty::IntTy::I128, chalk_ir::IntTy::I128) - ), - (ty::Uint(ty1), Scalar(Uint(ty2))) => matches!( - (ty1, ty2), - (ty::UintTy::Usize, chalk_ir::UintTy::Usize) - | (ty::UintTy::U8, chalk_ir::UintTy::U8) - | (ty::UintTy::U16, chalk_ir::UintTy::U16) - | (ty::UintTy::U32, chalk_ir::UintTy::U32) - | (ty::UintTy::U64, chalk_ir::UintTy::U64) - | (ty::UintTy::U128, chalk_ir::UintTy::U128) - ), - (ty::Float(ty1), Scalar(Float(ty2))) => matches!( - (ty1, ty2), - (ty::FloatTy::F32, chalk_ir::FloatTy::F32) - | (ty::FloatTy::F64, chalk_ir::FloatTy::F64) - ), - (&ty::Tuple(substs), Tuple(len, _)) => substs.len() == *len, - (&ty::Array(..), Array(..)) => true, - (&ty::Slice(..), Slice(..)) => true, - (&ty::RawPtr(type_and_mut), Raw(mutability, _)) => { - match (type_and_mut.mutbl, mutability) { - (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, - (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, - (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, - (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, - } - } - (&ty::Ref(.., mutability1), Ref(mutability2, ..)) => { - match (mutability1, mutability2) { - (ast::Mutability::Mut, chalk_ir::Mutability::Mut) => true, - (ast::Mutability::Mut, chalk_ir::Mutability::Not) => false, - (ast::Mutability::Not, chalk_ir::Mutability::Mut) => false, - (ast::Mutability::Not, chalk_ir::Mutability::Not) => true, - } - } - ( - &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), - OpaqueType(opaque_ty_id, ..), - ) => def_id == opaque_ty_id.0, - (&ty::FnDef(def_id, ..), FnDef(fn_def_id, ..)) => def_id == fn_def_id.0, - (&ty::Str, Str) => true, - (&ty::Never, Never) => true, - (&ty::Closure(def_id, ..), Closure(closure_id, _)) => def_id == closure_id.0, - (&ty::Foreign(def_id), Foreign(foreign_def_id)) => def_id == foreign_def_id.0, - (&ty::Error(..), Error) => false, - _ => false, - }; - if provides { - return true; - } - } - false - } - - fn associated_ty_value( - &self, - associated_ty_id: chalk_solve::rust_ir::AssociatedTyValueId>, - ) -> Arc>> { - let def_id = associated_ty_id.0; - let assoc_item = self.interner.tcx.associated_item(def_id); - let impl_id = assoc_item.container_id(self.interner.tcx); - match assoc_item.kind { - AssocKind::Type => {} - _ => unimplemented!("Not possible??"), - } - - let trait_item_id = assoc_item.trait_item_def_id.expect("assoc_ty with no trait version"); - let bound_vars = bound_vars_for_item(self.interner.tcx, def_id); - let binders = binders_for(self.interner, bound_vars); - let ty = self - .interner - .tcx - .type_of(def_id) - .subst(self.interner.tcx, bound_vars) - .lower_into(self.interner); - - Arc::new(chalk_solve::rust_ir::AssociatedTyValue { - impl_id: chalk_ir::ImplId(impl_id), - associated_ty_id: chalk_ir::AssocTypeId(trait_item_id), - value: chalk_ir::Binders::new( - binders, - chalk_solve::rust_ir::AssociatedTyValueBound { ty }, - ), - }) - } - - fn custom_clauses(&self) -> Vec>> { - vec![] - } - - fn local_impls_to_coherence_check( - &self, - _trait_id: chalk_ir::TraitId>, - ) -> Vec>> { - unimplemented!() - } - - fn opaque_ty_data( - &self, - opaque_ty_id: chalk_ir::OpaqueTyId>, - ) -> Arc>> { - let bound_vars = ty::fold::shift_vars( - self.interner.tcx, - bound_vars_for_item(self.interner.tcx, opaque_ty_id.0), - 1, - ); - let where_clauses = self.where_clauses_for(opaque_ty_id.0, bound_vars); - - let identity_substs = InternalSubsts::identity_for_item(self.interner.tcx, opaque_ty_id.0); - - let explicit_item_bounds = self.interner.tcx.explicit_item_bounds(opaque_ty_id.0); - let bounds = - explicit_item_bounds - .subst_iter_copied(self.interner.tcx, &bound_vars) - .map(|(bound, _)| { - bound.fold_with(&mut ReplaceOpaqueTyFolder { - tcx: self.interner.tcx, - opaque_ty_id, - identity_substs, - binder_index: ty::INNERMOST, - }) - }) - .filter_map(|bound| { - LowerInto::< - Option>> - >::lower_into(bound.as_predicate(), self.interner) - }) - .collect(); - - // Binder for the bound variable representing the concrete impl Trait type. - let existential_binder = chalk_ir::VariableKinds::from1( - self.interner, - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), - ); - - let value = chalk_solve::rust_ir::OpaqueTyDatumBound { - bounds: chalk_ir::Binders::new(existential_binder.clone(), bounds), - where_clauses: chalk_ir::Binders::new(existential_binder, where_clauses), - }; - - let binders = binders_for(self.interner, bound_vars); - Arc::new(chalk_solve::rust_ir::OpaqueTyDatum { - opaque_ty_id, - bound: chalk_ir::Binders::new(binders, value), - }) - } - - fn program_clauses_for_env( - &self, - environment: &chalk_ir::Environment>, - ) -> chalk_ir::ProgramClauses> { - chalk_solve::program_clauses_for_env(self, environment) - } - - fn well_known_trait_id( - &self, - well_known_trait: chalk_solve::rust_ir::WellKnownTrait, - ) -> Option>> { - use chalk_solve::rust_ir::WellKnownTrait::*; - let lang_items = self.interner.tcx.lang_items(); - let def_id = match well_known_trait { - Sized => lang_items.sized_trait(), - Copy => lang_items.copy_trait(), - Clone => lang_items.clone_trait(), - Drop => lang_items.drop_trait(), - Fn => lang_items.fn_trait(), - FnMut => lang_items.fn_mut_trait(), - FnOnce => lang_items.fn_once_trait(), - Generator => lang_items.gen_trait(), - Unsize => lang_items.unsize_trait(), - Unpin => lang_items.unpin_trait(), - CoerceUnsized => lang_items.coerce_unsized_trait(), - DiscriminantKind => lang_items.discriminant_kind_trait(), - DispatchFromDyn => lang_items.dispatch_from_dyn_trait(), - Tuple => lang_items.tuple_trait(), - Pointee => lang_items.pointee_trait(), - FnPtr => lang_items.fn_ptr_trait(), - }; - def_id.map(chalk_ir::TraitId) - } - - fn is_object_safe(&self, trait_id: chalk_ir::TraitId>) -> bool { - self.interner.tcx.check_is_object_safe(trait_id.0) - } - - fn hidden_opaque_type( - &self, - _id: chalk_ir::OpaqueTyId>, - ) -> chalk_ir::Ty> { - // FIXME(chalk): actually get hidden ty - self.interner.tcx.types.unit.lower_into(self.interner) - } - - fn closure_kind( - &self, - _closure_id: chalk_ir::ClosureId>, - substs: &chalk_ir::Substitution>, - ) -> chalk_solve::rust_ir::ClosureKind { - let kind = &substs.as_slice(self.interner)[substs.len(self.interner) - 3]; - match kind.assert_ty_ref(self.interner).kind(self.interner) { - chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(int_ty)) => match int_ty { - chalk_ir::IntTy::I8 => chalk_solve::rust_ir::ClosureKind::Fn, - chalk_ir::IntTy::I16 => chalk_solve::rust_ir::ClosureKind::FnMut, - chalk_ir::IntTy::I32 => chalk_solve::rust_ir::ClosureKind::FnOnce, - _ => bug!("bad closure kind"), - }, - _ => bug!("bad closure kind"), - } - } - - fn closure_inputs_and_output( - &self, - _closure_id: chalk_ir::ClosureId>, - substs: &chalk_ir::Substitution>, - ) -> chalk_ir::Binders>> - { - let sig = &substs.as_slice(self.interner)[substs.len(self.interner) - 2]; - match sig.assert_ty_ref(self.interner).kind(self.interner) { - chalk_ir::TyKind::Function(f) => { - let substitution = f.substitution.0.as_slice(self.interner); - let return_type = substitution.last().unwrap().assert_ty_ref(self.interner).clone(); - // Closure arguments are tupled - let argument_tuple = substitution[0].assert_ty_ref(self.interner); - let argument_types = match argument_tuple.kind(self.interner) { - chalk_ir::TyKind::Tuple(_len, substitution) => substitution - .iter(self.interner) - .map(|arg| arg.assert_ty_ref(self.interner)) - .cloned() - .collect(), - _ => bug!("Expecting closure FnSig args to be tupled."), - }; - - chalk_ir::Binders::new( - chalk_ir::VariableKinds::from_iter( - self.interner, - (0..f.num_binders).map(|_| chalk_ir::VariableKind::Lifetime), - ), - chalk_solve::rust_ir::FnDefInputsAndOutputDatum { argument_types, return_type }, - ) - } - _ => panic!("Invalid sig."), - } - } - - fn closure_upvars( - &self, - _closure_id: chalk_ir::ClosureId>, - substs: &chalk_ir::Substitution>, - ) -> chalk_ir::Binders>> { - let inputs_and_output = self.closure_inputs_and_output(_closure_id, substs); - let tuple = substs.as_slice(self.interner).last().unwrap().assert_ty_ref(self.interner); - inputs_and_output.map_ref(|_| tuple.clone()) - } - - fn closure_fn_substitution( - &self, - _closure_id: chalk_ir::ClosureId>, - substs: &chalk_ir::Substitution>, - ) -> chalk_ir::Substitution> { - let substitution = &substs.as_slice(self.interner)[0..substs.len(self.interner) - 3]; - chalk_ir::Substitution::from_iter(self.interner, substitution) - } - - fn generator_datum( - &self, - _generator_id: chalk_ir::GeneratorId>, - ) -> Arc>> { - unimplemented!() - } - - fn generator_witness_datum( - &self, - _generator_id: chalk_ir::GeneratorId>, - ) -> Arc>> { - unimplemented!() - } - - fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase> { - self - } - - fn discriminant_type( - &self, - _: chalk_ir::Ty>, - ) -> chalk_ir::Ty> { - unimplemented!() - } -} - -impl<'tcx> chalk_ir::UnificationDatabase> for RustIrDatabase<'tcx> { - fn fn_def_variance( - &self, - def_id: chalk_ir::FnDefId>, - ) -> chalk_ir::Variances> { - let variances = self.interner.tcx.variances_of(def_id.0); - chalk_ir::Variances::from_iter( - self.interner, - variances.iter().map(|v| v.lower_into(self.interner)), - ) - } - - fn adt_variance( - &self, - adt_id: chalk_ir::AdtId>, - ) -> chalk_ir::Variances> { - let variances = self.interner.tcx.variances_of(adt_id.0.did()); - chalk_ir::Variances::from_iter( - self.interner, - variances.iter().map(|v| v.lower_into(self.interner)), - ) - } -} - -/// Creates an `InternalSubsts` that maps each generic parameter to a higher-ranked -/// var bound at index `0`. For types, we use a `BoundVar` index equal to -/// the type parameter index. For regions, we use the `BoundRegionKind::BrNamed` -/// variant (which has a `DefId`). -fn bound_vars_for_item(tcx: TyCtxt<'_>, def_id: DefId) -> SubstsRef<'_> { - InternalSubsts::for_item(tcx, def_id, |param, substs| match param.kind { - ty::GenericParamDefKind::Type { .. } => tcx - .mk_bound( - ty::INNERMOST, - ty::BoundTy { - var: ty::BoundVar::from(param.index), - kind: ty::BoundTyKind::Param(param.def_id, param.name), - }, - ) - .into(), - - ty::GenericParamDefKind::Lifetime => { - let br = ty::BoundRegion { - var: ty::BoundVar::from_usize(substs.len()), - kind: ty::BrAnon(None), - }; - ty::Region::new_late_bound(tcx, ty::INNERMOST, br).into() - } - - ty::GenericParamDefKind::Const { .. } => tcx - .mk_const( - ty::ConstKind::Bound(ty::INNERMOST, ty::BoundVar::from(param.index)), - tcx.type_of(param.def_id).subst_identity(), - ) - .into(), - }) -} - -fn binders_for<'tcx>( - interner: RustInterner<'tcx>, - bound_vars: SubstsRef<'tcx>, -) -> chalk_ir::VariableKinds> { - chalk_ir::VariableKinds::from_iter( - interner, - bound_vars.iter().map(|arg| match arg.unpack() { - ty::subst::GenericArgKind::Lifetime(_re) => chalk_ir::VariableKind::Lifetime, - ty::subst::GenericArgKind::Type(_ty) => { - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General) - } - ty::subst::GenericArgKind::Const(c) => { - chalk_ir::VariableKind::Const(c.ty().lower_into(interner)) - } - }), - ) -} - -struct ReplaceOpaqueTyFolder<'tcx> { - tcx: TyCtxt<'tcx>, - opaque_ty_id: chalk_ir::OpaqueTyId>, - identity_substs: SubstsRef<'tcx>, - binder_index: ty::DebruijnIndex, -} - -impl<'tcx> ty::TypeFolder> for ReplaceOpaqueTyFolder<'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_binder>>( - &mut self, - t: ty::Binder<'tcx, T>, - ) -> ty::Binder<'tcx, T> { - self.binder_index.shift_in(1); - let t = t.super_fold_with(self); - self.binder_index.shift_out(1); - t - } - - fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) = *ty.kind() { - if def_id == self.opaque_ty_id.0 && substs == self.identity_substs { - return self - .tcx - .mk_bound(self.binder_index, ty::BoundTy::from(ty::BoundVar::from_u32(0))); - } - } - ty - } -} diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs deleted file mode 100644 index b7db56d3db8..00000000000 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ /dev/null @@ -1,1234 +0,0 @@ -//! Contains the logic to lower rustc types into Chalk types -//! -//! In many cases there is a 1:1 relationship between a rustc type and a Chalk type. -//! For example, a `SubstsRef` maps almost directly to a `Substitution`. In some -//! other cases, such as `Param`s, there is no Chalk type, so we have to handle -//! accordingly. -//! -//! ## `Ty` lowering -//! Much of the `Ty` lowering is 1:1 with Chalk. (Or will be eventually). A -//! helpful table for what types lower to what can be found in the -//! [Chalk book](https://rust-lang.github.io/chalk/book/types/rust_types.html). -//! The most notable difference lies with `Param`s. To convert from rustc to -//! Chalk, we eagerly and deeply convert `Param`s to placeholders (in goals) or -//! bound variables (for clause generation through functions in `db`). -//! -//! ## `Region` lowering -//! Regions are handled in rustc and Chalk is quite differently. In rustc, there -//! is a difference between "early bound" and "late bound" regions, where only -//! the late bound regions have a `DebruijnIndex`. Moreover, in Chalk all -//! regions (Lifetimes) have an associated index. In rustc, only `BrAnon`s have -//! an index, whereas `BrNamed` don't. In order to lower regions to Chalk, we -//! convert all regions into `BrAnon` late-bound regions. -//! -//! ## `Const` lowering -//! Chalk doesn't handle consts currently, so consts are currently lowered to -//! an empty tuple. -//! -//! ## Bound variable collection -//! Another difference between rustc and Chalk lies in the handling of binders. -//! Chalk requires that we store the bound parameter kinds, whereas rustc does -//! not. To lower anything wrapped in a `Binder`, we first deeply find any bound -//! variables from the current `Binder`. - -use rustc_ast::ast; -use rustc_middle::traits::{ChalkEnvironmentAndGoal, ChalkRustInterner as RustInterner}; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; -use rustc_middle::ty::{ - self, Binder, Region, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, - TypeSuperVisitable, TypeVisitable, TypeVisitor, -}; -use rustc_span::def_id::DefId; - -use chalk_ir::{FnSig, ForeignDefId}; -use rustc_hir::Unsafety; -use std::collections::btree_map::{BTreeMap, Entry}; -use std::ops::ControlFlow; - -/// Essentially an `Into` with a `&RustInterner` parameter -pub(crate) trait LowerInto<'tcx, T> { - /// Lower a rustc construct (e.g., `ty::TraitPredicate`) to a chalk type, consuming `self`. - fn lower_into(self, interner: RustInterner<'tcx>) -> T; -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution>> for SubstsRef<'tcx> { - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> chalk_ir::Substitution> { - chalk_ir::Substitution::from_iter(interner, self.iter().map(|s| s.lower_into(interner))) - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::Substitution>> - for &'tcx ty::List> -{ - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> chalk_ir::Substitution> { - chalk_ir::Substitution::from_iter( - interner, - self.iter().map(|ty| GenericArg::from(ty).lower_into(interner)), - ) - } -} - -impl<'tcx> LowerInto<'tcx, SubstsRef<'tcx>> for &chalk_ir::Substitution> { - fn lower_into(self, interner: RustInterner<'tcx>) -> SubstsRef<'tcx> { - interner - .tcx - .mk_substs_from_iter(self.iter(interner).map(|subst| subst.lower_into(interner))) - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment>>> - for ChalkEnvironmentAndGoal<'tcx> -{ - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> chalk_ir::InEnvironment>> { - let clauses = self.environment.into_iter().map(|predicate| { - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, predicate.kind()); - let consequence = match predicate { - ty::ClauseKind::TypeWellFormedFromEnv(ty) => { - chalk_ir::DomainGoal::FromEnv(chalk_ir::FromEnv::Ty(ty.lower_into(interner))) - } - ty::ClauseKind::Trait(predicate) => chalk_ir::DomainGoal::FromEnv( - chalk_ir::FromEnv::Trait(predicate.trait_ref.lower_into(interner)), - ), - ty::ClauseKind::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::ClauseKind::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::ClauseKind::Projection(predicate) => chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)), - ), - ty::ClauseKind::WellFormed(arg) => match arg.unpack() { - ty::GenericArgKind::Type(ty) => chalk_ir::DomainGoal::WellFormed( - chalk_ir::WellFormed::Ty(ty.lower_into(interner)), - ), - // FIXME(chalk): we need to change `WellFormed` in Chalk to take a `GenericArg` - _ => chalk_ir::DomainGoal::WellFormed(chalk_ir::WellFormed::Ty( - interner.tcx.types.unit.lower_into(interner), - )), - }, - ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::ConstEvaluatable(_) => { - 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) - }); - - let goal: chalk_ir::GoalData> = self.goal.lower_into(interner); - chalk_ir::InEnvironment { - environment: chalk_ir::Environment { - clauses: chalk_ir::ProgramClauses::from_iter(interner, clauses), - }, - goal: goal.intern(interner), - } - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData>> for ty::Predicate<'tcx> { - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::GoalData> { - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, self.kind()); - - let value = match predicate { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => { - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)), - )) - } - ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => { - 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), - }), - )) - } - ty::PredicateKind::Clause(ty::ClauseKind::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::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => { - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::Holds( - chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner)), - )) - } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => match arg.unpack() { - GenericArgKind::Type(ty) => match ty.kind() { - // 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::empty(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(..) => { - chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) - } - GenericArgKind::Lifetime(lt) => bug!("unexpected well formed predicate: {:?}", lt), - }, - - ty::PredicateKind::ObjectSafe(t) => chalk_ir::GoalData::DomainGoal( - chalk_ir::DomainGoal::ObjectSafe(chalk_ir::TraitId(t)), - ), - - ty::PredicateKind::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) => { - chalk_ir::GoalData::SubtypeGoal(chalk_ir::SubtypeGoal { - a: a.lower_into(interner), - b: b.lower_into(interner), - }) - } - - // FIXME(chalk): other predicates - // - // We can defer this, but ultimately we'll want to express - // some of these in terms of chalk operations. - ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::ConstEquate(..) => { - chalk_ir::GoalData::All(chalk_ir::Goals::empty(interner)) - } - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(ty)) => { - chalk_ir::GoalData::DomainGoal(chalk_ir::DomainGoal::FromEnv( - chalk_ir::FromEnv::Ty(ty.lower_into(interner)), - )) - } - }; - - chalk_ir::GoalData::Quantified( - chalk_ir::QuantifierKind::ForAll, - chalk_ir::Binders::new(binders, value.intern(interner)), - ) - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::TraitRef>> - for rustc_middle::ty::TraitRef<'tcx> -{ - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::TraitRef> { - chalk_ir::TraitRef { - trait_id: chalk_ir::TraitId(self.def_id), - substitution: self.substs.lower_into(interner), - } - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::AliasEq>> - for rustc_middle::ty::ProjectionPredicate<'tcx> -{ - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::AliasEq> { - // FIXME(associated_const_equality): teach chalk about terms for alias eq. - chalk_ir::AliasEq { - ty: self.term.ty().unwrap().lower_into(interner), - alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.def_id), - substitution: self.projection_ty.substs.lower_into(interner), - }), - } - } -} - -/* -// FIXME(...): Where do I add this to Chalk? I can't find it in the rustc repo anywhere. -impl<'tcx> LowerInto<'tcx, chalk_ir::Term>> for rustc_middle::ty::Term<'tcx> { - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::Term> { - match self { - ty::Term::Ty(ty) => ty.lower_into(interner).into(), - ty::Term::Const(c) => c.lower_into(interner).into(), - } - } -} -*/ - -impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::Ty> { - let int = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Int(i)); - let uint = |i| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Uint(i)); - let float = |f| chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Float(f)); - - match *self.kind() { - ty::Bool => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Bool), - ty::Char => chalk_ir::TyKind::Scalar(chalk_ir::Scalar::Char), - ty::Int(ty) => match ty { - ty::IntTy::Isize => int(chalk_ir::IntTy::Isize), - ty::IntTy::I8 => int(chalk_ir::IntTy::I8), - ty::IntTy::I16 => int(chalk_ir::IntTy::I16), - ty::IntTy::I32 => int(chalk_ir::IntTy::I32), - ty::IntTy::I64 => int(chalk_ir::IntTy::I64), - ty::IntTy::I128 => int(chalk_ir::IntTy::I128), - }, - ty::Uint(ty) => match ty { - ty::UintTy::Usize => uint(chalk_ir::UintTy::Usize), - ty::UintTy::U8 => uint(chalk_ir::UintTy::U8), - ty::UintTy::U16 => uint(chalk_ir::UintTy::U16), - ty::UintTy::U32 => uint(chalk_ir::UintTy::U32), - ty::UintTy::U64 => uint(chalk_ir::UintTy::U64), - ty::UintTy::U128 => uint(chalk_ir::UintTy::U128), - }, - ty::Float(ty) => match ty { - ty::FloatTy::F32 => float(chalk_ir::FloatTy::F32), - ty::FloatTy::F64 => float(chalk_ir::FloatTy::F64), - }, - ty::Adt(def, substs) => { - chalk_ir::TyKind::Adt(chalk_ir::AdtId(def), substs.lower_into(interner)) - } - ty::Foreign(def_id) => chalk_ir::TyKind::Foreign(ForeignDefId(def_id)), - ty::Str => chalk_ir::TyKind::Str, - ty::Array(ty, len) => { - chalk_ir::TyKind::Array(ty.lower_into(interner), len.lower_into(interner)) - } - ty::Slice(ty) => chalk_ir::TyKind::Slice(ty.lower_into(interner)), - - ty::RawPtr(ptr) => { - chalk_ir::TyKind::Raw(ptr.mutbl.lower_into(interner), ptr.ty.lower_into(interner)) - } - ty::Ref(region, ty, mutability) => chalk_ir::TyKind::Ref( - mutability.lower_into(interner), - region.lower_into(interner), - ty.lower_into(interner), - ), - ty::FnDef(def_id, substs) => { - chalk_ir::TyKind::FnDef(chalk_ir::FnDefId(def_id), substs.lower_into(interner)) - } - ty::FnPtr(sig) => { - let (inputs_and_outputs, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, sig.inputs_and_output()); - chalk_ir::TyKind::Function(chalk_ir::FnPointer { - num_binders: binders.len(interner), - sig: sig.lower_into(interner), - substitution: chalk_ir::FnSubst(chalk_ir::Substitution::from_iter( - interner, - inputs_and_outputs.iter().map(|ty| { - chalk_ir::GenericArgData::Ty(ty.lower_into(interner)).intern(interner) - }), - )), - }) - } - // FIXME(dyn-star): handle the dynamic kind (dyn or dyn*) - ty::Dynamic(predicates, region, _kind) => chalk_ir::TyKind::Dyn(chalk_ir::DynTy { - bounds: predicates.lower_into(interner), - lifetime: region.lower_into(interner), - }), - ty::Closure(def_id, substs) => { - chalk_ir::TyKind::Closure(chalk_ir::ClosureId(def_id), substs.lower_into(interner)) - } - ty::Generator(def_id, substs, _) => chalk_ir::TyKind::Generator( - chalk_ir::GeneratorId(def_id), - substs.lower_into(interner), - ), - ty::GeneratorWitness(_) => unimplemented!(), - ty::GeneratorWitnessMIR(..) => unimplemented!(), - ty::Never => chalk_ir::TyKind::Never, - ty::Tuple(types) => chalk_ir::TyKind::Tuple(types.len(), types.lower_into(interner)), - ty::Alias(ty::Projection, ty::AliasTy { def_id, substs, .. }) => { - chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(def_id), - substitution: substs.lower_into(interner), - })) - } - ty::Alias(ty::Weak, ty::AliasTy { .. }) => unimplemented!(), - ty::Alias(ty::Inherent, _) => unimplemented!(), - ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { - chalk_ir::TyKind::Alias(chalk_ir::AliasTy::Opaque(chalk_ir::OpaqueTy { - opaque_ty_id: chalk_ir::OpaqueTyId(def_id), - substitution: substs.lower_into(interner), - })) - } - // This should have been done eagerly prior to this, and all Params - // should have been substituted to placeholders - ty::Param(_) => panic!("Lowering Param when not expected."), - ty::Bound(db, bound) => chalk_ir::TyKind::BoundVar(chalk_ir::BoundVar::new( - chalk_ir::DebruijnIndex::new(db.as_u32()), - bound.var.index(), - )), - ty::Placeholder(_placeholder) => { - chalk_ir::TyKind::Placeholder(chalk_ir::PlaceholderIndex { - ui: chalk_ir::UniverseIndex { counter: _placeholder.universe.as_usize() }, - idx: _placeholder.bound.var.as_usize(), - }) - } - ty::Infer(_infer) => unimplemented!(), - ty::Error(_) => chalk_ir::TyKind::Error, - } - .intern(interner) - } -} - -impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty> { - fn lower_into(self, interner: RustInterner<'tcx>) -> Ty<'tcx> { - use chalk_ir::TyKind; - - let kind = match self.kind(interner) { - TyKind::Adt(struct_id, substitution) => { - ty::Adt(struct_id.0, substitution.lower_into(interner)) - } - TyKind::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(ty::IntTy::Isize), - chalk_ir::IntTy::I8 => ty::Int(ty::IntTy::I8), - chalk_ir::IntTy::I16 => ty::Int(ty::IntTy::I16), - chalk_ir::IntTy::I32 => ty::Int(ty::IntTy::I32), - chalk_ir::IntTy::I64 => ty::Int(ty::IntTy::I64), - chalk_ir::IntTy::I128 => ty::Int(ty::IntTy::I128), - }, - chalk_ir::Scalar::Uint(int_ty) => match int_ty { - chalk_ir::UintTy::Usize => ty::Uint(ty::UintTy::Usize), - chalk_ir::UintTy::U8 => ty::Uint(ty::UintTy::U8), - chalk_ir::UintTy::U16 => ty::Uint(ty::UintTy::U16), - chalk_ir::UintTy::U32 => ty::Uint(ty::UintTy::U32), - chalk_ir::UintTy::U64 => ty::Uint(ty::UintTy::U64), - chalk_ir::UintTy::U128 => ty::Uint(ty::UintTy::U128), - }, - chalk_ir::Scalar::Float(float_ty) => match float_ty { - chalk_ir::FloatTy::F32 => ty::Float(ty::FloatTy::F32), - chalk_ir::FloatTy::F64 => ty::Float(ty::FloatTy::F64), - }, - }, - TyKind::Array(ty, c) => { - let ty = ty.lower_into(interner); - let c = c.lower_into(interner); - ty::Array(ty, c) - } - TyKind::FnDef(id, substitution) => ty::FnDef(id.0, substitution.lower_into(interner)), - TyKind::Closure(closure, substitution) => { - ty::Closure(closure.0, substitution.lower_into(interner)) - } - TyKind::Generator(generator, substitution) => ty::Generator( - generator.0, - substitution.lower_into(interner), - ast::Movability::Static, - ), - TyKind::GeneratorWitness(..) => unimplemented!(), - TyKind::Never => ty::Never, - TyKind::Tuple(_len, substitution) => { - ty::Tuple(substitution.lower_into(interner).into_type_list(interner.tcx)) - } - TyKind::Slice(ty) => ty::Slice(ty.lower_into(interner)), - TyKind::Raw(mutbl, ty) => ty::RawPtr(ty::TypeAndMut { - ty: ty.lower_into(interner), - mutbl: mutbl.lower_into(interner), - }), - TyKind::Ref(mutbl, lifetime, ty) => ty::Ref( - lifetime.lower_into(interner), - ty.lower_into(interner), - mutbl.lower_into(interner), - ), - TyKind::Str => ty::Str, - TyKind::OpaqueType(opaque_ty, substitution) => ty::Alias( - ty::Opaque, - interner.tcx.mk_alias_ty(opaque_ty.0, substitution.lower_into(interner)), - ), - TyKind::AssociatedType(assoc_ty, substitution) => ty::Alias( - ty::Projection, - interner.tcx.mk_alias_ty(assoc_ty.0, substitution.lower_into(interner)), - ), - TyKind::Foreign(def_id) => ty::Foreign(def_id.0), - TyKind::Error => return interner.tcx.ty_error_misc(), - TyKind::Alias(alias_ty) => match alias_ty { - chalk_ir::AliasTy::Projection(projection) => ty::Alias( - ty::Projection, - interner.tcx.mk_alias_ty( - projection.associated_ty_id.0, - projection.substitution.lower_into(interner), - ), - ), - chalk_ir::AliasTy::Opaque(opaque) => ty::Alias( - ty::Opaque, - interner.tcx.mk_alias_ty( - opaque.opaque_ty_id.0, - opaque.substitution.lower_into(interner), - ), - ), - }, - TyKind::Function(_quantified_ty) => unimplemented!(), - TyKind::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, - }, - ), - TyKind::Placeholder(placeholder) => ty::Placeholder(ty::Placeholder { - universe: ty::UniverseIndex::from_usize(placeholder.ui.counter), - bound: ty::BoundTy { - var: ty::BoundVar::from_usize(placeholder.idx), - kind: ty::BoundTyKind::Anon, - }, - }), - TyKind::InferenceVar(_, _) => unimplemented!(), - TyKind::Dyn(_) => unimplemented!(), - }; - interner.tcx.mk_ty_from_kind(kind) - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::Lifetime>> for Region<'tcx> { - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::Lifetime> { - match *self { - ty::ReEarlyBound(_) => { - panic!("Should have already been substituted."); - } - ty::ReError(_) => { - panic!("Error lifetime should not have already been lowered."); - } - ty::ReLateBound(db, br) => chalk_ir::LifetimeData::BoundVar(chalk_ir::BoundVar::new( - chalk_ir::DebruijnIndex::new(db.as_u32()), - br.var.as_usize(), - )) - .intern(interner), - ty::ReFree(_) => unimplemented!(), - ty::ReStatic => chalk_ir::LifetimeData::Static.intern(interner), - ty::ReVar(_) => unimplemented!(), - ty::RePlaceholder(placeholder_region) => { - chalk_ir::LifetimeData::Placeholder(chalk_ir::PlaceholderIndex { - ui: chalk_ir::UniverseIndex { counter: placeholder_region.universe.index() }, - idx: 0, // FIXME: This `idx: 0` is sus. - }) - .intern(interner) - } - ty::ReErased => chalk_ir::LifetimeData::Erased.intern(interner), - } - } -} - -impl<'tcx> LowerInto<'tcx, Region<'tcx>> for &chalk_ir::Lifetime> { - fn lower_into(self, interner: RustInterner<'tcx>) -> Region<'tcx> { - let tcx = interner.tcx; - match self.data(interner) { - chalk_ir::LifetimeData::BoundVar(var) => ty::Region::new_late_bound( - tcx, - ty::DebruijnIndex::from_u32(var.debruijn.depth()), - ty::BoundRegion { - var: ty::BoundVar::from_usize(var.index), - kind: ty::BrAnon(None), - }, - ), - chalk_ir::LifetimeData::InferenceVar(_var) => unimplemented!(), - chalk_ir::LifetimeData::Placeholder(p) => ty::Region::new_placeholder( - tcx, - ty::Placeholder { - universe: ty::UniverseIndex::from_usize(p.ui.counter), - bound: ty::BoundRegion { - var: ty::BoundVar::from_usize(p.idx), - kind: ty::BoundRegionKind::BrAnon(None), - }, - }, - ), - chalk_ir::LifetimeData::Static => tcx.lifetimes.re_static, - chalk_ir::LifetimeData::Erased => tcx.lifetimes.re_erased, - chalk_ir::LifetimeData::Phantom(void, _) => match *void {}, - } - } -} - -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.kind() { - 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 kind = 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), - }; - interner.tcx.mk_const(kind, ty) - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::GenericArg>> for GenericArg<'tcx> { - fn lower_into(self, interner: RustInterner<'tcx>) -> chalk_ir::GenericArg> { - match self.unpack() { - ty::subst::GenericArgKind::Type(ty) => { - chalk_ir::GenericArgData::Ty(ty.lower_into(interner)) - } - ty::subst::GenericArgKind::Lifetime(lifetime) => { - chalk_ir::GenericArgData::Lifetime(lifetime.lower_into(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); - 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 -// eventually be removed. -impl<'tcx> LowerInto<'tcx, Option>>> - for ty::Predicate<'tcx> -{ - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> Option>> { - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, self.kind()); - let value = match predicate { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => { - Some(chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner))) - } - ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(predicate)) => { - Some(chalk_ir::WhereClause::LifetimeOutlives(chalk_ir::LifetimeOutlives { - a: predicate.0.lower_into(interner), - b: predicate.1.lower_into(interner), - })) - } - ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(predicate)) => { - Some(chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives { - ty: predicate.0.lower_into(interner), - lifetime: predicate.1.lower_into(interner), - })) - } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => { - Some(chalk_ir::WhereClause::AliasEq(predicate.lower_into(interner))) - } - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_ty)) => None, - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => None, - - ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - bug!("unexpected predicate {self}") - } - }; - value.map(|value| chalk_ir::Binders::new(binders, value)) - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::Binders>>> - for &'tcx ty::List> -{ - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> chalk_ir::Binders>> { - // `Self` has one binder: - // Binder<&'tcx ty::List>> - // The return type has two: - // Binders<&[Binders>]> - // This means that any variables that are escaping `self` need to be - // shifted in by one so that they are still escaping. - let predicates = ty::fold::shift_vars(interner.tcx, self, 1); - - let self_ty = interner.tcx.mk_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| { - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, predicate); - match predicate { - ty::ExistentialPredicate::Trait(ty::ExistentialTraitRef { def_id, substs }) => { - chalk_ir::Binders::new( - binders.clone(), - chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { - trait_id: chalk_ir::TraitId(def_id), - substitution: interner - .tcx - .mk_substs_trait(self_ty, substs) - .lower_into(interner), - }), - ) - } - ty::ExistentialPredicate::Projection(predicate) => chalk_ir::Binders::new( - binders.clone(), - chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { - alias: chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(predicate.def_id), - substitution: interner - .tcx - .mk_substs_trait(self_ty, predicate.substs) - .lower_into(interner), - }), - // FIXME(associated_const_equality): teach chalk about terms for alias eq. - ty: predicate.term.ty().unwrap().lower_into(interner), - }), - ), - ty::ExistentialPredicate::AutoTrait(def_id) => chalk_ir::Binders::new( - binders.clone(), - chalk_ir::WhereClause::Implemented(chalk_ir::TraitRef { - trait_id: chalk_ir::TraitId(def_id), - substitution: interner - .tcx - .mk_substs_trait(self_ty, []) - .lower_into(interner), - }), - ), - } - }); - - // Binder for the bound variable representing the concrete underlying type. - let existential_binder = chalk_ir::VariableKinds::from1( - interner, - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), - ); - let value = chalk_ir::QuantifiedWhereClauses::from_iter(interner, where_clauses); - chalk_ir::Binders::new(existential_binder, value) - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::FnSig>> - for ty::Binder<'tcx, ty::FnSig<'tcx>> -{ - fn lower_into(self, _interner: RustInterner<'_>) -> FnSig> { - chalk_ir::FnSig { - abi: self.abi(), - safety: match self.unsafety() { - Unsafety::Normal => chalk_ir::Safety::Safe, - Unsafety::Unsafe => chalk_ir::Safety::Unsafe, - }, - variadic: self.c_variadic(), - } - } -} - -// We lower into an Option here since there are some predicates which Chalk -// doesn't have a representation for yet (as an `InlineBound`). The `Option` will -// eventually be removed. -impl<'tcx> LowerInto<'tcx, Option>>> - for ty::Predicate<'tcx> -{ - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> Option>> { - let (predicate, binders, _named_regions) = - collect_bound_vars(interner, interner.tcx, self.kind()); - match predicate { - ty::PredicateKind::Clause(ty::ClauseKind::Trait(predicate)) => { - Some(chalk_ir::Binders::new( - binders, - chalk_solve::rust_ir::InlineBound::TraitBound( - predicate.trait_ref.lower_into(interner), - ), - )) - } - ty::PredicateKind::Clause(ty::ClauseKind::Projection(predicate)) => { - Some(chalk_ir::Binders::new( - binders, - chalk_solve::rust_ir::InlineBound::AliasEqBound(predicate.lower_into(interner)), - )) - } - ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(_predicate)) => None, - ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(_ty)) => None, - ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..)) => None, - - ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(..)) - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::ObjectSafe(..) - | ty::PredicateKind::ClosureKind(..) - | ty::PredicateKind::Subtype(..) - | ty::PredicateKind::Coerce(..) - | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) - | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - bug!("unexpected predicate {}", &self) - } - } - } -} - -impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::TraitBound>> - for ty::TraitRef<'tcx> -{ - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> chalk_solve::rust_ir::TraitBound> { - chalk_solve::rust_ir::TraitBound { - trait_id: chalk_ir::TraitId(self.def_id), - args_no_self: self.substs[1..].iter().map(|arg| arg.lower_into(interner)).collect(), - } - } -} - -impl<'tcx> LowerInto<'tcx, chalk_ir::Mutability> for ast::Mutability { - fn lower_into(self, _interner: RustInterner<'tcx>) -> chalk_ir::Mutability { - match self { - rustc_ast::Mutability::Mut => chalk_ir::Mutability::Mut, - rustc_ast::Mutability::Not => chalk_ir::Mutability::Not, - } - } -} - -impl<'tcx> LowerInto<'tcx, ast::Mutability> for chalk_ir::Mutability { - fn lower_into(self, _interner: RustInterner<'tcx>) -> ast::Mutability { - match self { - chalk_ir::Mutability::Mut => ast::Mutability::Mut, - chalk_ir::Mutability::Not => ast::Mutability::Not, - } - } -} - -impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::Polarity> for ty::ImplPolarity { - fn lower_into(self, _interner: RustInterner<'tcx>) -> chalk_solve::rust_ir::Polarity { - match self { - ty::ImplPolarity::Positive => chalk_solve::rust_ir::Polarity::Positive, - ty::ImplPolarity::Negative => chalk_solve::rust_ir::Polarity::Negative, - // FIXME(chalk) reservation impls - ty::ImplPolarity::Reservation => chalk_solve::rust_ir::Polarity::Negative, - } - } -} -impl<'tcx> LowerInto<'tcx, chalk_ir::Variance> for ty::Variance { - fn lower_into(self, _interner: RustInterner<'tcx>) -> chalk_ir::Variance { - match self { - ty::Variance::Covariant => chalk_ir::Variance::Covariant, - ty::Variance::Invariant => chalk_ir::Variance::Invariant, - ty::Variance::Contravariant => chalk_ir::Variance::Contravariant, - ty::Variance::Bivariant => unimplemented!(), - } - } -} - -impl<'tcx> LowerInto<'tcx, chalk_solve::rust_ir::AliasEqBound>> - for ty::ProjectionPredicate<'tcx> -{ - fn lower_into( - self, - interner: RustInterner<'tcx>, - ) -> chalk_solve::rust_ir::AliasEqBound> { - let (trait_ref, own_substs) = self.projection_ty.trait_ref_and_own_substs(interner.tcx); - chalk_solve::rust_ir::AliasEqBound { - trait_bound: trait_ref.lower_into(interner), - associated_ty_id: chalk_ir::AssocTypeId(self.projection_ty.def_id), - parameters: own_substs.iter().map(|arg| arg.lower_into(interner)).collect(), - value: self.term.ty().unwrap().lower_into(interner), - } - } -} - -/// To collect bound vars, we have to do two passes. In the first pass, we -/// collect all `BoundRegionKind`s and `ty::Bound`s. In the second pass, we then -/// replace `BrNamed` into `BrAnon`. The two separate passes are important, -/// since we can only replace `BrNamed` with `BrAnon`s with indices *after* all -/// "real" `BrAnon`s. -/// -/// It's important to note that because of prior substitution, we may have -/// late-bound regions, even outside of fn contexts, since this is the best way -/// to prep types for chalk lowering. -pub(crate) fn collect_bound_vars<'tcx, T: TypeFoldable>>( - interner: RustInterner<'tcx>, - tcx: TyCtxt<'tcx>, - ty: Binder<'tcx, T>, -) -> (T, chalk_ir::VariableKinds>, BTreeMap) { - let mut bound_vars_collector = BoundVarsCollector::new(); - ty.as_ref().skip_binder().visit_with(&mut bound_vars_collector); - let mut parameters = bound_vars_collector.parameters; - let named_parameters: BTreeMap = bound_vars_collector - .named_parameters - .into_iter() - .enumerate() - .map(|(i, def_id)| (def_id, (i + parameters.len()) as u32)) - .collect(); - - let mut bound_var_substitutor = NamedBoundVarSubstitutor::new(tcx, &named_parameters); - let new_ty = ty.skip_binder().fold_with(&mut bound_var_substitutor); - - for var in named_parameters.values() { - parameters.insert(*var, chalk_ir::VariableKind::Lifetime); - } - - (0..parameters.len()).for_each(|i| { - parameters - .get(&(i as u32)) - .or_else(|| bug!("Skipped bound var index: parameters={:?}", parameters)); - }); - - let binders = chalk_ir::VariableKinds::from_iter(interner, parameters.into_values()); - - (new_ty, binders, named_parameters) -} - -pub(crate) struct BoundVarsCollector<'tcx> { - binder_index: ty::DebruijnIndex, - pub(crate) parameters: BTreeMap>>, - pub(crate) named_parameters: Vec, -} - -impl<'tcx> BoundVarsCollector<'tcx> { - pub(crate) fn new() -> Self { - BoundVarsCollector { - binder_index: ty::INNERMOST, - parameters: BTreeMap::new(), - named_parameters: vec![], - } - } -} - -impl<'tcx> TypeVisitor> for BoundVarsCollector<'tcx> { - fn visit_binder>>( - &mut self, - t: &Binder<'tcx, T>, - ) -> ControlFlow { - self.binder_index.shift_in(1); - let result = t.super_visit_with(self); - self.binder_index.shift_out(1); - result - } - - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - match *t.kind() { - ty::Bound(debruijn, bound_ty) if debruijn == self.binder_index => { - match self.parameters.entry(bound_ty.var.as_u32()) { - Entry::Vacant(entry) => { - entry.insert(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)); - } - Entry::Occupied(entry) => match entry.get() { - chalk_ir::VariableKind::Ty(_) => {} - _ => panic!(), - }, - } - } - - _ => (), - }; - - t.super_visit_with(self) - } - - fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { - match *r { - ty::ReLateBound(index, br) if index == self.binder_index => match br.kind { - ty::BoundRegionKind::BrNamed(def_id, _name) => { - if !self.named_parameters.iter().any(|d| *d == def_id) { - self.named_parameters.push(def_id); - } - } - - ty::BoundRegionKind::BrAnon(_) => match self.parameters.entry(br.var.as_u32()) { - Entry::Vacant(entry) => { - entry.insert(chalk_ir::VariableKind::Lifetime); - } - Entry::Occupied(entry) => match entry.get() { - chalk_ir::VariableKind::Lifetime => {} - _ => panic!(), - }, - }, - - ty::BoundRegionKind::BrEnv => unimplemented!(), - }, - - ty::ReEarlyBound(_re) => { - // FIXME(chalk): jackh726 - I think we should always have already - // substituted away `ReEarlyBound`s for `ReLateBound`s, but need to confirm. - unimplemented!(); - } - - _ => (), - }; - - ControlFlow::Continue(()) - } -} - -/// This is used to replace `BoundRegionKind::BrNamed` with `BoundRegionKind::BrAnon`. -/// Note: we assume that we will always have room for more bound vars. (i.e. we -/// won't ever hit the `u32` limit in `BrAnon`s). -struct NamedBoundVarSubstitutor<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - binder_index: ty::DebruijnIndex, - named_parameters: &'a BTreeMap, -} - -impl<'a, 'tcx> NamedBoundVarSubstitutor<'a, 'tcx> { - fn new(tcx: TyCtxt<'tcx>, named_parameters: &'a BTreeMap) -> Self { - NamedBoundVarSubstitutor { tcx, binder_index: ty::INNERMOST, named_parameters } - } -} - -impl<'a, 'tcx> TypeFolder> for NamedBoundVarSubstitutor<'a, 'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_binder>>( - &mut self, - t: Binder<'tcx, T>, - ) -> Binder<'tcx, T> { - self.binder_index.shift_in(1); - let result = t.super_fold_with(self); - self.binder_index.shift_out(1); - result - } - - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { - match *r { - ty::ReLateBound(index, br) if index == self.binder_index => match br.kind { - ty::BrNamed(def_id, _name) => match self.named_parameters.get(&def_id) { - Some(_) => { - let new_br = ty::BoundRegion { var: br.var, kind: ty::BrAnon(None) }; - return ty::Region::new_late_bound(self.tcx, index, new_br); - } - None => panic!("Missing `BrNamed`."), - }, - ty::BrEnv => unimplemented!(), - ty::BrAnon(..) => {} - }, - _ => (), - }; - - r - } -} - -/// Used to substitute `Param`s with placeholders. We do this since Chalk -/// have a notion of `Param`s. -pub(crate) struct ParamsSubstitutor<'tcx> { - tcx: TyCtxt<'tcx>, - binder_index: ty::DebruijnIndex, - list: Vec, - next_ty_placeholder: usize, - pub(crate) params: rustc_data_structures::fx::FxHashMap, - pub(crate) named_regions: BTreeMap, -} - -impl<'tcx> ParamsSubstitutor<'tcx> { - pub(crate) fn new(tcx: TyCtxt<'tcx>, next_ty_placeholder: usize) -> Self { - ParamsSubstitutor { - tcx, - binder_index: ty::INNERMOST, - list: vec![], - next_ty_placeholder, - params: rustc_data_structures::fx::FxHashMap::default(), - named_regions: BTreeMap::default(), - } - } -} - -impl<'tcx> TypeFolder> for ParamsSubstitutor<'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_binder>>( - &mut self, - t: Binder<'tcx, T>, - ) -> Binder<'tcx, T> { - self.binder_index.shift_in(1); - let result = t.super_fold_with(self); - self.binder_index.shift_out(1); - result - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - match *t.kind() { - ty::Param(param) => match self.list.iter().position(|r| r == ¶m) { - Some(idx) => self.tcx.mk_placeholder(ty::PlaceholderType { - universe: ty::UniverseIndex::from_usize(0), - bound: ty::BoundTy { - var: ty::BoundVar::from_usize(idx), - kind: ty::BoundTyKind::Anon, - }, - }), - None => { - self.list.push(param); - let idx = self.list.len() - 1 + self.next_ty_placeholder; - self.params.insert(idx as u32, param); - self.tcx.mk_placeholder(ty::PlaceholderType { - universe: ty::UniverseIndex::from_usize(0), - bound: ty::BoundTy { - var: ty::BoundVar::from_usize(idx), - kind: ty::BoundTyKind::Anon, - }, - }) - } - }, - _ => t.super_fold_with(self), - } - } - - fn fold_region(&mut self, r: Region<'tcx>) -> Region<'tcx> { - match *r { - // FIXME(chalk) - jackh726 - this currently isn't hit in any tests, - // since canonicalization will already change these to canonical - // variables (ty::ReLateBound). - ty::ReEarlyBound(_re) => match self.named_regions.get(&_re.def_id) { - Some(idx) => { - let br = ty::BoundRegion { - var: ty::BoundVar::from_u32(*idx), - kind: ty::BrAnon(None), - }; - ty::Region::new_late_bound(self.tcx, self.binder_index, br) - } - None => { - let idx = self.named_regions.len() as u32; - let br = ty::BoundRegion { - var: ty::BoundVar::from_u32(idx), - kind: ty::BrAnon(None), - }; - self.named_regions.insert(_re.def_id, idx); - ty::Region::new_late_bound(self.tcx, self.binder_index, br) - } - }, - - _ => r, - } - } -} - -pub(crate) struct ReverseParamsSubstitutor<'tcx> { - tcx: TyCtxt<'tcx>, - params: rustc_data_structures::fx::FxHashMap, -} - -impl<'tcx> ReverseParamsSubstitutor<'tcx> { - pub(crate) fn new( - tcx: TyCtxt<'tcx>, - params: rustc_data_structures::fx::FxHashMap, - ) -> Self { - Self { tcx, params } - } -} - -impl<'tcx> TypeFolder> for ReverseParamsSubstitutor<'tcx> { - fn interner(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { - match *t.kind() { - ty::Placeholder(ty::PlaceholderType { universe: ty::UniverseIndex::ROOT, bound }) => { - match self.params.get(&bound.var.as_u32()) { - Some(&ty::ParamTy { index, name }) => self.tcx.mk_ty_param(index, name), - None => t, - } - } - - _ => t.super_fold_with(self), - } - } -} - -/// Used to collect `Placeholder`s. -pub(crate) struct PlaceholdersCollector { - universe_index: ty::UniverseIndex, - pub(crate) next_ty_placeholder: usize, - pub(crate) next_anon_region_placeholder: u32, -} - -impl PlaceholdersCollector { - pub(crate) fn new() -> Self { - PlaceholdersCollector { - universe_index: ty::UniverseIndex::ROOT, - next_ty_placeholder: 0, - next_anon_region_placeholder: 0, - } - } -} - -impl<'tcx> TypeVisitor> for PlaceholdersCollector { - fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow { - match t.kind() { - ty::Placeholder(p) if p.universe == self.universe_index => { - self.next_ty_placeholder = self.next_ty_placeholder.max(p.bound.var.as_usize() + 1); - } - - _ => (), - }; - - t.super_visit_with(self) - } - - fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow { - match *r { - ty::RePlaceholder(p) if p.universe == self.universe_index => { - if let ty::BoundRegionKind::BrAnon(_) = p.bound.kind { - self.next_anon_region_placeholder = - self.next_anon_region_placeholder.max(p.bound.var.as_u32()); - } - // FIXME: This doesn't seem to handle BrNamed at all? - } - - _ => (), - }; - - ControlFlow::Continue(()) - } -} diff --git a/compiler/rustc_traits/src/chalk/mod.rs b/compiler/rustc_traits/src/chalk/mod.rs deleted file mode 100644 index 8834449c9a4..00000000000 --- a/compiler/rustc_traits/src/chalk/mod.rs +++ /dev/null @@ -1,169 +0,0 @@ -//! Calls `chalk-solve` to solve a `ty::Predicate` -//! -//! In order to call `chalk-solve`, this file must convert a `CanonicalChalkEnvironmentAndGoal` into -//! a Chalk uncanonical goal. It then calls Chalk, and converts the answer back into rustc solution. - -pub(crate) mod db; -pub(crate) mod lowering; - -use rustc_middle::infer::canonical::{CanonicalTyVarKind, CanonicalVarKind}; -use rustc_middle::query::Providers; -use rustc_middle::traits::ChalkRustInterner; -use rustc_middle::ty::{self, TyCtxt, TypeFoldable, TypeVisitable}; - -use rustc_infer::infer::canonical::{ - Canonical, CanonicalVarValues, Certainty, QueryRegionConstraints, QueryResponse, -}; -use rustc_infer::traits::{self, CanonicalChalkEnvironmentAndGoal}; - -use crate::chalk::db::RustIrDatabase as ChalkRustIrDatabase; -use crate::chalk::lowering::LowerInto; -use crate::chalk::lowering::{ParamsSubstitutor, PlaceholdersCollector, ReverseParamsSubstitutor}; - -use chalk_solve::Solution; - -pub(crate) fn provide(p: &mut Providers) { - *p = Providers { evaluate_goal, ..*p }; -} - -pub(crate) fn evaluate_goal<'tcx>( - tcx: TyCtxt<'tcx>, - obligation: CanonicalChalkEnvironmentAndGoal<'tcx>, -) -> Result<&'tcx Canonical<'tcx, QueryResponse<'tcx, ()>>, traits::query::NoSolution> { - let interner = ChalkRustInterner { tcx }; - - // Chalk doesn't have a notion of `Params`, so instead we use placeholders. - let mut placeholders_collector = PlaceholdersCollector::new(); - obligation.visit_with(&mut placeholders_collector); - - let mut params_substitutor = - ParamsSubstitutor::new(tcx, placeholders_collector.next_ty_placeholder); - let obligation = obligation.fold_with(&mut params_substitutor); - let params = params_substitutor.params; - - let max_universe = obligation.max_universe.index(); - - let lowered_goal: chalk_ir::UCanonical< - chalk_ir::InEnvironment>>, - > = chalk_ir::UCanonical { - canonical: chalk_ir::Canonical { - binders: chalk_ir::CanonicalVarKinds::from_iter( - interner, - obligation.variables.iter().map(|v| match v.kind { - CanonicalVarKind::PlaceholderTy(_ty) => unimplemented!(), - CanonicalVarKind::PlaceholderRegion(_ui) => unimplemented!(), - CanonicalVarKind::Ty(ty) => match ty { - CanonicalTyVarKind::General(ui) => chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), - chalk_ir::UniverseIndex { counter: ui.index() }, - ), - CanonicalTyVarKind::Int => chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Integer), - chalk_ir::UniverseIndex::root(), - ), - CanonicalTyVarKind::Float => chalk_ir::WithKind::new( - chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::Float), - chalk_ir::UniverseIndex::root(), - ), - }, - CanonicalVarKind::Region(ui) => chalk_ir::WithKind::new( - chalk_ir::VariableKind::Lifetime, - chalk_ir::UniverseIndex { counter: ui.index() }, - ), - CanonicalVarKind::Const(_ui, _ty) => unimplemented!(), - CanonicalVarKind::PlaceholderConst(_pc, _ty) => unimplemented!(), - }), - ), - value: obligation.value.lower_into(interner), - }, - universes: max_universe + 1, - }; - - use chalk_solve::Solver; - let mut solver = chalk_engine::solve::SLGSolver::new(32, None); - let db = ChalkRustIrDatabase { interner }; - debug!(?lowered_goal); - let solution = solver.solve(&db, &lowered_goal); - debug!(?obligation, ?solution, "evaluate 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<_>, - binders: chalk_ir::CanonicalVarKinds<_>| { - use rustc_middle::infer::canonical::CanonicalVarInfo; - - let mut reverse_param_substitutor = ReverseParamsSubstitutor::new(tcx, params); - let var_values = tcx.mk_substs_from_iter( - subst - .as_slice(interner) - .iter() - .map(|p| p.lower_into(interner).fold_with(&mut reverse_param_substitutor)), - ); - let variables = binders.iter(interner).map(|var| { - let kind = match var.kind { - chalk_ir::VariableKind::Ty(ty_kind) => CanonicalVarKind::Ty(match ty_kind { - chalk_ir::TyVariableKind::General => CanonicalTyVarKind::General( - ty::UniverseIndex::from_usize(var.skip_kind().counter), - ), - chalk_ir::TyVariableKind::Integer => CanonicalTyVarKind::Int, - chalk_ir::TyVariableKind::Float => CanonicalTyVarKind::Float, - }), - chalk_ir::VariableKind::Lifetime => { - CanonicalVarKind::Region(ty::UniverseIndex::from_usize(var.skip_kind().counter)) - } - // FIXME(compiler-errors): We don't currently have a way of turning - // a Chalk ty back into a rustc ty, right? - chalk_ir::VariableKind::Const(_) => todo!(), - }; - CanonicalVarInfo { kind } - }); - let max_universe = binders.iter(interner).map(|v| v.skip_kind().counter).max().unwrap_or(0); - let sol = Canonical { - max_universe: ty::UniverseIndex::from_usize(max_universe), - variables: tcx.mk_canonical_var_infos_from_iter(variables), - value: QueryResponse { - var_values: CanonicalVarValues { var_values }, - region_constraints: QueryRegionConstraints::default(), - certainty: Certainty::Proven, - opaque_types: vec![], - value: (), - }, - }; - tcx.arena.alloc(sol) - }; - solution - .map(|s| match s { - Solution::Unique(subst) => { - // FIXME(chalk): handle constraints - make_solution(subst.value.subst, subst.binders) - } - Solution::Ambig(guidance) => { - match guidance { - chalk_solve::Guidance::Definite(subst) => { - make_solution(subst.value, subst.binders) - } - chalk_solve::Guidance::Suggested(_) => unimplemented!(), - chalk_solve::Guidance::Unknown => { - // chalk_fulfill doesn't use the var_values here, so - // let's just ignore that - let sol = Canonical { - max_universe: ty::UniverseIndex::from_usize(0), - variables: obligation.variables, - value: QueryResponse { - var_values: CanonicalVarValues::dummy(), - region_constraints: QueryRegionConstraints::default(), - certainty: Certainty::Ambiguous, - opaque_types: vec![], - value: (), - }, - }; - &*tcx.arena.alloc(sol) - } - } - } - }) - .ok_or(traits::query::NoSolution) -} diff --git a/compiler/rustc_traits/src/lib.rs b/compiler/rustc_traits/src/lib.rs index 590d0bd0e42..dfa5814219b 100644 --- a/compiler/rustc_traits/src/lib.rs +++ b/compiler/rustc_traits/src/lib.rs @@ -1,5 +1,4 @@ -//! New recursive solver modeled on Chalk's recursive solver. Most of -//! the guts are broken up into modules; see the comments in those modules. +//! Queries that are independent from the main solver code. #![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::diagnostic_outside_of_impl)] @@ -11,7 +10,6 @@ extern crate tracing; #[macro_use] extern crate rustc_middle; -mod chalk; mod codegen; mod dropck_outlives; mod evaluate_obligation; @@ -29,7 +27,6 @@ pub fn provide(p: &mut Providers) { dropck_outlives::provide(p); evaluate_obligation::provide(p); implied_outlives_bounds::provide(p); - chalk::provide(p); normalize_projection_ty::provide(p); normalize_erasing_regions::provide(p); type_op::provide(p); diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 2b391f94a63..eecc54635ff 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -1,4 +1,4 @@ -use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; +use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::def::DefKind; use rustc_index::bit_set::BitSet; @@ -7,7 +7,6 @@ use rustc_middle::ty::{ self, EarlyBinder, ImplTraitInTraitData, ToPredicate, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, }; -use rustc_session::config::TraitSolver; use rustc_span::def_id::{DefId, LocalDefId, CRATE_DEF_ID}; use rustc_span::DUMMY_SP; use rustc_trait_selection::traits; @@ -148,11 +147,6 @@ fn param_env(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { // are any errors at that point, so outside of type inference you can be // sure that this will succeed without errors anyway. - if tcx.sess.opts.unstable_opts.trait_solver == TraitSolver::Chalk { - let environment = well_formed_types_in_env(tcx, def_id); - predicates.extend(environment); - } - if tcx.def_kind(def_id) == DefKind::AssocFn && tcx.associated_item(def_id).container == ty::AssocItemContainer::TraitContainer { @@ -336,116 +330,6 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { } } -/// Elaborate the environment. -/// -/// Collect a list of `Predicate`'s used for building the `ParamEnv`. Adds `TypeWellFormedFromEnv`'s -/// that are assumed to be well-formed (because they come from the environment). -/// -/// Used only in chalk mode. -fn well_formed_types_in_env(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::List> { - use rustc_hir::{ForeignItemKind, ImplItemKind, ItemKind, Node, TraitItemKind}; - - debug!("environment(def_id = {:?})", def_id); - - // The environment of an impl Trait type is its defining function's environment. - if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) { - return well_formed_types_in_env(tcx, parent.to_def_id()); - } - - // Compute the bounds on `Self` and the type parameters. - let ty::InstantiatedPredicates { predicates, .. } = - tcx.predicates_of(def_id).instantiate_identity(tcx); - - let clauses = predicates.into_iter(); - - if !def_id.is_local() { - return ty::List::empty(); - } - let node = tcx.hir().get_by_def_id(def_id.expect_local()); - - enum NodeKind { - TraitImpl, - InherentImpl, - Fn, - Other, - } - - let node_kind = match node { - Node::TraitItem(item) => match item.kind { - TraitItemKind::Fn(..) => NodeKind::Fn, - _ => NodeKind::Other, - }, - - Node::ImplItem(item) => match item.kind { - ImplItemKind::Fn(..) => NodeKind::Fn, - _ => NodeKind::Other, - }, - - Node::Item(item) => match item.kind { - ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }) => NodeKind::TraitImpl, - ItemKind::Impl(hir::Impl { of_trait: None, .. }) => NodeKind::InherentImpl, - ItemKind::Fn(..) => NodeKind::Fn, - _ => NodeKind::Other, - }, - - Node::ForeignItem(item) => match item.kind { - ForeignItemKind::Fn(..) => NodeKind::Fn, - _ => NodeKind::Other, - }, - - // FIXME: closures? - _ => NodeKind::Other, - }; - - // FIXME(eddyb) isn't the unordered nature of this a hazard? - let mut inputs = FxIndexSet::default(); - - match node_kind { - // In a trait impl, we assume that the header trait ref and all its - // constituents are well-formed. - NodeKind::TraitImpl => { - let trait_ref = tcx.impl_trait_ref(def_id).expect("not an impl").subst_identity(); - - // FIXME(chalk): this has problems because of late-bound regions - //inputs.extend(trait_ref.substs.iter().flat_map(|arg| arg.walk())); - inputs.extend(trait_ref.substs.iter()); - } - - // In an inherent impl, we assume that the receiver type and all its - // constituents are well-formed. - NodeKind::InherentImpl => { - let self_ty = tcx.type_of(def_id).subst_identity(); - inputs.extend(self_ty.walk()); - } - - // In an fn, we assume that the arguments and all their constituents are - // well-formed. - NodeKind::Fn => { - let fn_sig = tcx.fn_sig(def_id).subst_identity(); - let fn_sig = tcx.liberate_late_bound_regions(def_id, fn_sig); - - inputs.extend(fn_sig.inputs().iter().flat_map(|ty| ty.walk())); - } - - NodeKind::Other => (), - } - let input_clauses = inputs.into_iter().filter_map(|arg| { - match arg.unpack() { - ty::GenericArgKind::Type(ty) => { - Some(ty::ClauseKind::TypeWellFormedFromEnv(ty).to_predicate(tcx)) - } - - // FIXME(eddyb) no WF conditions from lifetimes? - ty::GenericArgKind::Lifetime(_) => None, - - // FIXME(eddyb) support const generics in Chalk - ty::GenericArgKind::Const(_) => None, - } - }); - - tcx.mk_clauses_from_iter(clauses.chain(input_clauses)) -} - fn param_env_reveal_all_normalized(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ParamEnv<'_> { tcx.param_env(def_id).with_reveal_all_normalized(tcx) } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index e1ee11e41c3..a70ffc3e798 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -149,7 +149,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "fallible-iterator", // dependency of `thorin` "fastrand", "field-offset", - "fixedbitset", "flate2", "fluent-bundle", "fluent-langneg", @@ -199,7 +198,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "parking_lot_core", "pathdiff", "perf-event-open-sys", - "petgraph", "pin-project-lite", "polonius-engine", "ppv-lite86", diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 3ed587caadc..55bf38110a6 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -11,7 +11,7 @@ use std::path::{Path, PathBuf}; const ENTRY_LIMIT: usize = 900; // FIXME: The following limits should be reduced eventually. const ISSUES_ENTRY_LIMIT: usize = 1896; -const ROOT_ENTRY_LIMIT: usize = 871; +const ROOT_ENTRY_LIMIT: usize = 870; const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[ "rs", // test source files diff --git a/tests/ui/chalkify/arithmetic.rs b/tests/ui/chalkify/arithmetic.rs deleted file mode 100644 index 6c78a71b0fc..00000000000 --- a/tests/ui/chalkify/arithmetic.rs +++ /dev/null @@ -1,20 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -fn main() { - 1 + 2; - 3 * 6; - 2 - 5; - 17 / 6; - 23 % 11; - 4 & 6; - 7 | 15; - 4 << 7; - 123 >> 3; - 1 == 2; - 5 != 5; - 6 < 2; - 7 > 11; - 3 <= 1; - 9 >= 14; -} diff --git a/tests/ui/chalkify/assert.rs b/tests/ui/chalkify/assert.rs deleted file mode 100644 index 834c8935e76..00000000000 --- a/tests/ui/chalkify/assert.rs +++ /dev/null @@ -1,6 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -fn main() { - assert_eq!(1, 1); -} diff --git a/tests/ui/chalkify/basic.rs b/tests/ui/chalkify/basic.rs deleted file mode 100644 index 4a7cd939669..00000000000 --- a/tests/ui/chalkify/basic.rs +++ /dev/null @@ -1,12 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo {} - -struct Bar {} - -impl Foo for Bar {} - -fn main() -> () { - let _ = Bar {}; -} diff --git a/tests/ui/chalkify/bugs/async.rs b/tests/ui/chalkify/bugs/async.rs deleted file mode 100644 index a1ef4732b63..00000000000 --- a/tests/ui/chalkify/bugs/async.rs +++ /dev/null @@ -1,25 +0,0 @@ -// edition:2021 -// known-bug: unknown -// unset-rustc-env:RUST_BACKTRACE -// compile-flags:-Z trait-solver=chalk -// error-pattern:internal compiler error -// failure-status:101 -// normalize-stderr-test "DefId\([^)]*\)" -> "..." -// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" -// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" -// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -// normalize-stderr-test "note: compiler flags.*\n\n" -> "" -// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -// normalize-stderr-test "thread.*panicked.*\n" -> "" -// normalize-stderr-test "stack backtrace:\n" -> "" -// normalize-stderr-test "\s\d{1,}: .*\n" -> "" -// normalize-stderr-test "\s at .*\n" -> "" -// normalize-stderr-test ".*note: Some details.*\n" -> "" -// normalize-stderr-test "\n\n[ ]*\n" -> "" -// normalize-stderr-test "compiler/.*: projection" -> "projection" - -fn main() -> () {} - -async fn foo(x: u32) -> u32 { - x -} diff --git a/tests/ui/chalkify/bugs/async.stderr b/tests/ui/chalkify/bugs/async.stderr deleted file mode 100644 index 9ebaac31dcb..00000000000 --- a/tests/ui/chalkify/bugs/async.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0277]: `[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future - --> $DIR/async.rs:23:25 - | -LL | async fn foo(x: u32) -> u32 { - | ^^^ `[async fn body@$DIR/async.rs:23:29: 25:2]` is not a future - | - = help: the trait `Future` is not implemented for `[async fn body@$DIR/async.rs:23:29: 25:2]` - = note: [async fn body@$DIR/async.rs:23:29: 25:2] must be a future or must implement `IntoFuture` to be awaited - -error: internal compiler error: projection clauses should be implied from elsewhere. obligation: `Obligation(predicate=Binder { value: ProjectionPredicate(AliasTy { substs: [[async fn body@$DIR/async.rs:23:29: 25:2]], def_id: ... }, Term::Ty(u32)), bound_vars: [] }, depth=0)` - --> $DIR/async.rs:23:25 - | -LL | async fn foo(x: u32) -> u32 { - | ^^^query stack during panic: -#0 [typeck] type-checking `foo` -#1 [type_of] computing type of `foo::{opaque#0}` -#2 [check_mod_item_types] checking item types in top-level module -#3 [analysis] running analysis passes on this crate -end of query stack -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/builtin-copy-clone.rs b/tests/ui/chalkify/builtin-copy-clone.rs deleted file mode 100644 index a478c006ef1..00000000000 --- a/tests/ui/chalkify/builtin-copy-clone.rs +++ /dev/null @@ -1,45 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -// Test that `Clone` is correctly implemented for builtin types. - -#[derive(Copy, Clone)] -struct S(#[allow(unused_tuple_struct_fields)] i32); - -fn test_clone(arg: T) { - let _ = arg.clone(); -} - -fn test_copy(arg: T) { - let _ = arg; - let _ = arg; -} - -fn test_copy_clone(arg: T) { - test_copy(arg); - test_clone(arg); -} - -fn foo() { } - -fn main() { - // FIXME: add closures when they're considered WF - test_copy_clone(foo); - let f: fn() = foo; - test_copy_clone(f); - // FIXME(#86252): reinstate array test after chalk upgrade - //test_copy_clone([1; 56]); - test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)); - test_copy_clone((1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, true, 'a', 1.1)); - test_copy_clone(()); - test_copy_clone(((1, 1), (1, 1, 1), (1.1, 1, 1, 'a'), ())); - - let a = ( - (S(1), S(0)), - ( - (S(0), S(0), S(1)), - S(0) - ) - ); - test_copy_clone(a); -} diff --git a/tests/ui/chalkify/chalk_initial_program.rs b/tests/ui/chalkify/chalk_initial_program.rs deleted file mode 100644 index 21de72b6fcc..00000000000 --- a/tests/ui/chalkify/chalk_initial_program.rs +++ /dev/null @@ -1,16 +0,0 @@ -// compile-flags: -Z trait-solver=chalk - -trait Foo { } - -impl Foo for i32 { } - -impl Foo for u32 { } - -fn gimme() { } - -// Note: this also tests that `std::process::Termination` is implemented for `()`. -fn main() { - gimme::(); - gimme::(); - gimme::(); //~ERROR the trait bound `f32: Foo` is not satisfied -} diff --git a/tests/ui/chalkify/chalk_initial_program.stderr b/tests/ui/chalkify/chalk_initial_program.stderr deleted file mode 100644 index 343c0a31862..00000000000 --- a/tests/ui/chalkify/chalk_initial_program.stderr +++ /dev/null @@ -1,18 +0,0 @@ -error[E0277]: the trait bound `f32: Foo` is not satisfied - --> $DIR/chalk_initial_program.rs:15:13 - | -LL | gimme::(); - | ^^^ the trait `Foo` is not implemented for `f32` - | - = help: the following other types implement trait `Foo`: - i32 - u32 -note: required by a bound in `gimme` - --> $DIR/chalk_initial_program.rs:9:13 - | -LL | fn gimme() { } - | ^^^ required by this bound in `gimme` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/closure.rs b/tests/ui/chalkify/closure.rs deleted file mode 100644 index a908a1e97ec..00000000000 --- a/tests/ui/chalkify/closure.rs +++ /dev/null @@ -1,38 +0,0 @@ -// compile-flags: -Z trait-solver=chalk - -fn main() -> () { - let t = || {}; - t(); - - let mut a = 0; - let mut b = move || { - a = 1; - }; - b(); - - let mut c = b; - - c(); - b(); - - let mut a = 0; - let mut b = || { - a = 1; - }; - b(); - - let mut c = b; - - c(); - b(); //~ ERROR - - // FIXME(chalk): this doesn't quite work - /* - let b = |c| { - c - }; - - let a = &32; - b(a); - */ -} diff --git a/tests/ui/chalkify/closure.stderr b/tests/ui/chalkify/closure.stderr deleted file mode 100644 index a33c0ba0d37..00000000000 --- a/tests/ui/chalkify/closure.stderr +++ /dev/null @@ -1,22 +0,0 @@ -error[E0382]: borrow of moved value: `b` - --> $DIR/closure.rs:27:5 - | -LL | let mut c = b; - | - value moved here -... -LL | b(); - | ^ value borrowed here after move - | -note: closure cannot be moved more than once as it is not `Copy` due to moving the variable `a` out of its environment - --> $DIR/closure.rs:20:9 - | -LL | a = 1; - | ^ -help: consider mutably borrowing `b` - | -LL | let mut c = &mut b; - | ++++ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0382`. diff --git a/tests/ui/chalkify/generic_impls.rs b/tests/ui/chalkify/generic_impls.rs deleted file mode 100644 index 7d33e12d8be..00000000000 --- a/tests/ui/chalkify/generic_impls.rs +++ /dev/null @@ -1,18 +0,0 @@ -// compile-flags: -Z trait-solver=chalk - -trait Foo { } - -impl Foo for (T, u32) { } - -fn gimme() { } - -fn foo() { - gimme::<(T, u32)>(); - gimme::<(Option, u32)>(); - gimme::<(Option, f32)>(); //~ ERROR -} - -fn main() { - gimme::<(i32, u32)>(); - gimme::<(i32, f32)>(); //~ ERROR -} diff --git a/tests/ui/chalkify/generic_impls.stderr b/tests/ui/chalkify/generic_impls.stderr deleted file mode 100644 index d4a8354d3fc..00000000000 --- a/tests/ui/chalkify/generic_impls.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: the trait bound `(Option, f32): Foo` is not satisfied - --> $DIR/generic_impls.rs:12:13 - | -LL | gimme::<(Option, f32)>(); - | ^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `(Option, f32)` - | - = help: the trait `Foo` is implemented for `(T, u32)` -note: required by a bound in `gimme` - --> $DIR/generic_impls.rs:7:13 - | -LL | fn gimme() { } - | ^^^ required by this bound in `gimme` - -error[E0277]: the trait bound `(i32, f32): Foo` is not satisfied - --> $DIR/generic_impls.rs:17:13 - | -LL | gimme::<(i32, f32)>(); - | ^^^^^^^^^^ the trait `Foo` is not implemented for `(i32, f32)` - | - = help: the trait `Foo` is implemented for `(T, u32)` -note: required by a bound in `gimme` - --> $DIR/generic_impls.rs:7:13 - | -LL | fn gimme() { } - | ^^^ required by this bound in `gimme` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/impl_wf.rs b/tests/ui/chalkify/impl_wf.rs deleted file mode 100644 index c8dfd4c3a5b..00000000000 --- a/tests/ui/chalkify/impl_wf.rs +++ /dev/null @@ -1,26 +0,0 @@ -// compile-flags: -Z trait-solver=chalk - -trait Foo: Sized { } - -trait Bar { - type Item: Foo; -} - -impl Foo for i32 { } - -impl Foo for str { } -//~^ ERROR the size for values of type `str` cannot be known at compilation time - - -// Implicit `T: Sized` bound. -impl Foo for Option { } - -trait Baz where U: Foo { } - -impl Baz for i32 { } - -impl Baz for f32 { } -//~^ ERROR the trait bound `f32: Foo` is not satisfied - -fn main() { -} diff --git a/tests/ui/chalkify/impl_wf.stderr b/tests/ui/chalkify/impl_wf.stderr deleted file mode 100644 index 84c32fa3771..00000000000 --- a/tests/ui/chalkify/impl_wf.stderr +++ /dev/null @@ -1,29 +0,0 @@ -error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/impl_wf.rs:11:14 - | -LL | impl Foo for str { } - | ^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `str` -note: required by a bound in `Foo` - --> $DIR/impl_wf.rs:3:12 - | -LL | trait Foo: Sized { } - | ^^^^^ required by this bound in `Foo` - -error[E0277]: the trait bound `f32: Foo` is not satisfied - --> $DIR/impl_wf.rs:22:19 - | -LL | impl Baz for f32 { } - | ^^^ the trait `Foo` is not implemented for `f32` - | - = help: the trait `Foo` is implemented for `i32` -note: required by a bound in `Baz` - --> $DIR/impl_wf.rs:18:31 - | -LL | trait Baz where U: Foo { } - | ^^^ required by this bound in `Baz` - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/impl_wf_2.rs b/tests/ui/chalkify/impl_wf_2.rs deleted file mode 100644 index 325044ad634..00000000000 --- a/tests/ui/chalkify/impl_wf_2.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Split out of impl_wf.rs to work around rust aborting compilation early - -// compile-flags: -Z trait-solver=chalk - -trait Foo: Sized { } - -trait Bar { - type Item: Foo; -} - -impl Foo for i32 { } - -// Implicit `T: Sized` bound. -impl Foo for Option { } - -impl Bar for () { - type Item = i32; -} - -impl Bar for Option { - type Item = Option; -} - -impl Bar for f32 { - type Item = f32; - //~^ ERROR the trait bound `f32: Foo` is not satisfied -} - -trait Baz where U: Foo { } - -impl Baz for i32 { } - -fn main() {} diff --git a/tests/ui/chalkify/impl_wf_2.stderr b/tests/ui/chalkify/impl_wf_2.stderr deleted file mode 100644 index 1c1df644b06..00000000000 --- a/tests/ui/chalkify/impl_wf_2.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0277]: the trait bound `f32: Foo` is not satisfied - --> $DIR/impl_wf_2.rs:25:17 - | -LL | type Item = f32; - | ^^^ the trait `Foo` is not implemented for `f32` - | - = help: the trait `Foo` is implemented for `i32` -note: required by a bound in `Bar::Item` - --> $DIR/impl_wf_2.rs:8:16 - | -LL | type Item: Foo; - | ^^^ required by this bound in `Bar::Item` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/inherent_impl.rs b/tests/ui/chalkify/inherent_impl.rs deleted file mode 100644 index f0f24d485cd..00000000000 --- a/tests/ui/chalkify/inherent_impl.rs +++ /dev/null @@ -1,42 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo { } - -impl Foo for i32 { } - -struct S { - x: T, -} - -fn only_foo(_x: &T) { } - -impl S { - // Test that we have the correct environment inside an inherent method. - fn dummy_foo(&self) { - only_foo(&self.x) - } -} - -trait Bar { } -impl Bar for u32 { } - -fn only_bar() { } - -impl S { - // Test that the environment of `dummy_bar` adds up with the environment - // of the inherent impl. - fn dummy_bar(&self) { - only_foo(&self.x); - only_bar::(); - } -} - -fn main() { - let s = S { - x: 5, - }; - - s.dummy_bar::(); - s.dummy_foo(); -} diff --git a/tests/ui/chalkify/inherent_impl_min.rs b/tests/ui/chalkify/inherent_impl_min.rs deleted file mode 100644 index 3eda7102dec..00000000000 --- a/tests/ui/chalkify/inherent_impl_min.rs +++ /dev/null @@ -1,27 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo { } - -impl Foo for i32 { } - -struct S { - x: T, -} - -fn only_foo(_x: &T) { } - -impl S { - // Test that we have the correct environment inside an inherent method. - fn dummy_foo(&self) { - only_foo(&self.x) - } -} - -fn main() { - let s = S { - x: 5, - }; - - s.dummy_foo(); -} diff --git a/tests/ui/chalkify/lower_env1.rs b/tests/ui/chalkify/lower_env1.rs deleted file mode 100644 index c8762001e6a..00000000000 --- a/tests/ui/chalkify/lower_env1.rs +++ /dev/null @@ -1,14 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -#![allow(dead_code)] - -trait Foo { } - -trait Bar where Self: Foo { } - -fn bar() { -} - -fn main() { -} diff --git a/tests/ui/chalkify/lower_env2.rs b/tests/ui/chalkify/lower_env2.rs deleted file mode 100644 index 7d4f81f12ea..00000000000 --- a/tests/ui/chalkify/lower_env2.rs +++ /dev/null @@ -1,16 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -#![allow(dead_code)] - -trait Foo { } - -struct S<'a, T: ?Sized> where T: Foo { - data: &'a T, -} - -fn bar(_x: S<'_, T>) { // note that we have an implicit `T: Sized` bound -} - -fn main() { -} diff --git a/tests/ui/chalkify/lower_env3.rs b/tests/ui/chalkify/lower_env3.rs deleted file mode 100644 index 5b70c4abbb5..00000000000 --- a/tests/ui/chalkify/lower_env3.rs +++ /dev/null @@ -1,16 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -#![allow(dead_code)] - -trait Foo { - fn foo(&self); -} - -impl Foo for T where T: Clone { - fn foo(&self) { - } -} - -fn main() { -} diff --git a/tests/ui/chalkify/lower_impl.rs b/tests/ui/chalkify/lower_impl.rs deleted file mode 100644 index 6f79b3ba386..00000000000 --- a/tests/ui/chalkify/lower_impl.rs +++ /dev/null @@ -1,17 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo { } - -impl Foo for T where T: Iterator { } - -trait Bar { - type Assoc; -} - -impl Bar for T where T: Iterator { - type Assoc = Vec; -} - -fn main() { -} diff --git a/tests/ui/chalkify/lower_struct.rs b/tests/ui/chalkify/lower_struct.rs deleted file mode 100644 index 6be0d4dd5bd..00000000000 --- a/tests/ui/chalkify/lower_struct.rs +++ /dev/null @@ -1,8 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -struct Foo<'a, T> where Box: Clone { - _x: std::marker::PhantomData<&'a T>, -} - -fn main() { } diff --git a/tests/ui/chalkify/lower_trait.rs b/tests/ui/chalkify/lower_trait.rs deleted file mode 100644 index 8f5b358220b..00000000000 --- a/tests/ui/chalkify/lower_trait.rs +++ /dev/null @@ -1,11 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -trait Bar { } - -trait Foo { - type Assoc: Bar + ?Sized; -} - -fn main() { -} diff --git a/tests/ui/chalkify/lower_trait_higher_rank.rs b/tests/ui/chalkify/lower_trait_higher_rank.rs deleted file mode 100644 index f04a1deea87..00000000000 --- a/tests/ui/chalkify/lower_trait_higher_rank.rs +++ /dev/null @@ -1,9 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8 -{ -} - -fn main() { -} diff --git a/tests/ui/chalkify/lower_trait_where_clause.rs b/tests/ui/chalkify/lower_trait_where_clause.rs deleted file mode 100644 index a21d2f31963..00000000000 --- a/tests/ui/chalkify/lower_trait_where_clause.rs +++ /dev/null @@ -1,16 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -use std::borrow::Borrow; - -trait Foo<'a, 'b, T, U> -where - T: Borrow + ?Sized, - U: ?Sized + 'b, - 'a: 'b, - Box:, // NOTE(#53696) this checks an empty list of bounds. -{ -} - -fn main() { -} diff --git a/tests/ui/chalkify/println.rs b/tests/ui/chalkify/println.rs deleted file mode 100644 index edddc382152..00000000000 --- a/tests/ui/chalkify/println.rs +++ /dev/null @@ -1,6 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -fn main() { - println!("hello"); -} diff --git a/tests/ui/chalkify/projection.rs b/tests/ui/chalkify/projection.rs deleted file mode 100644 index 19bb2ae1497..00000000000 --- a/tests/ui/chalkify/projection.rs +++ /dev/null @@ -1,25 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo { } - -trait Bar { - type Item: Foo; -} - -impl Foo for i32 { } -impl Bar for i32 { - type Item = i32; -} - -fn only_foo() { } - -fn only_bar() { - // `T` implements `Bar` hence `::Item` must also implement `Bar` - only_foo::() -} - -fn main() { - only_bar::(); - only_foo::<::Item>(); -} diff --git a/tests/ui/chalkify/recursive_where_clause_on_type.rs b/tests/ui/chalkify/recursive_where_clause_on_type.rs deleted file mode 100644 index c2c8aa6aabe..00000000000 --- a/tests/ui/chalkify/recursive_where_clause_on_type.rs +++ /dev/null @@ -1,30 +0,0 @@ -// FIXME(chalk): should fail, see comments -// check-fail -// compile-flags: -Z trait-solver=chalk - -#![feature(trivial_bounds)] - -trait Bar { - fn foo(); -} -trait Foo: Bar { } - -struct S where S: Foo; - -impl Foo for S { -} - -fn bar() { - T::foo(); -} - -fn foo() { - bar::() -} - -fn main() { - // For some reason, the error is duplicated... - - foo::() //~ ERROR the type `S` is not well-formed - //~^ ERROR the type `S` is not well-formed -} diff --git a/tests/ui/chalkify/recursive_where_clause_on_type.stderr b/tests/ui/chalkify/recursive_where_clause_on_type.stderr deleted file mode 100644 index cead5adeaaa..00000000000 --- a/tests/ui/chalkify/recursive_where_clause_on_type.stderr +++ /dev/null @@ -1,14 +0,0 @@ -error: the type `S` is not well-formed - --> $DIR/recursive_where_clause_on_type.rs:28:11 - | -LL | foo::() - | ^ - -error: the type `S` is not well-formed - --> $DIR/recursive_where_clause_on_type.rs:28:5 - | -LL | foo::() - | ^^^^^^^^ - -error: aborting due to 2 previous errors - diff --git a/tests/ui/chalkify/super_trait.rs b/tests/ui/chalkify/super_trait.rs deleted file mode 100644 index 540ae51e57f..00000000000 --- a/tests/ui/chalkify/super_trait.rs +++ /dev/null @@ -1,19 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo { } -trait Bar: Foo { } - -impl Foo for i32 { } -impl Bar for i32 { } - -fn only_foo() { } - -fn only_bar() { - // `T` implements `Bar` hence `T` must also implement `Foo` - only_foo::() -} - -fn main() { - only_bar::() -} diff --git a/tests/ui/chalkify/trait-objects.rs b/tests/ui/chalkify/trait-objects.rs deleted file mode 100644 index 144d9788b82..00000000000 --- a/tests/ui/chalkify/trait-objects.rs +++ /dev/null @@ -1,12 +0,0 @@ -// check-pass -// compile-flags: -Z trait-solver=chalk - -use std::fmt::Display; - -fn main() { - let d: &dyn Display = &mut 3; - d.to_string(); - (&d).to_string(); - let f: &dyn Fn(i32) -> _ = &|x| x + x; - f(2); -} diff --git a/tests/ui/chalkify/trait_implied_bound.rs b/tests/ui/chalkify/trait_implied_bound.rs deleted file mode 100644 index f97dbf6b7e7..00000000000 --- a/tests/ui/chalkify/trait_implied_bound.rs +++ /dev/null @@ -1,18 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -trait Foo { } -trait Bar where U: Foo { } - -impl Foo for i32 { } -impl Bar for i32 { } - -fn only_foo() { } - -fn only_bar>() { - only_foo::() -} - -fn main() { - only_bar::() -} diff --git a/tests/ui/chalkify/type_implied_bound.rs b/tests/ui/chalkify/type_implied_bound.rs deleted file mode 100644 index 70f1b4265e4..00000000000 --- a/tests/ui/chalkify/type_implied_bound.rs +++ /dev/null @@ -1,29 +0,0 @@ -// run-pass -// compile-flags: -Z trait-solver=chalk - -trait Eq { } -trait Hash: Eq { } - -impl Eq for i32 { } -impl Hash for i32 { } - -struct Set { - _x: T, -} - -fn only_eq() { } - -fn take_a_set(_: &Set) { - // `Set` is an input type of `take_a_set`, hence we know that - // `T` must implement `Hash`, and we know in turn that `T` must - // implement `Eq`. - only_eq::() -} - -fn main() { - let set = Set { - _x: 5, - }; - - take_a_set(&set); -} diff --git a/tests/ui/chalkify/type_inference.rs b/tests/ui/chalkify/type_inference.rs deleted file mode 100644 index d7167d0dc57..00000000000 --- a/tests/ui/chalkify/type_inference.rs +++ /dev/null @@ -1,28 +0,0 @@ -// compile-flags: -Z trait-solver=chalk - -trait Foo { } -impl Foo for i32 { } - -trait Bar { } -impl Bar for i32 { } -impl Bar for u32 { } - -fn only_foo(_x: T) { } - -fn only_bar(_x: T) { } - -fn main() { - let x = 5.0; - - // The only type which implements `Foo` is `i32`, so the chalk trait solver - // is expecting a variable of type `i32`. This behavior differs from the - // old-style trait solver. I guess this will change, that's why I'm - // adding that test. - // FIXME(chalk): order of these two errors is non-deterministic, - // so let's just hide one for now - //only_foo(x); // ERROR the trait bound `f64: Foo` is not satisfied - - // Here we have two solutions so we get back the behavior of the old-style - // trait solver. - only_bar(x); //~ ERROR the trait bound `{float}: Bar` is not satisfied -} diff --git a/tests/ui/chalkify/type_inference.stderr b/tests/ui/chalkify/type_inference.stderr deleted file mode 100644 index 508a6dd1388..00000000000 --- a/tests/ui/chalkify/type_inference.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error[E0277]: the trait bound `{float}: Bar` is not satisfied - --> $DIR/type_inference.rs:27:14 - | -LL | only_bar(x); - | -------- ^ the trait `Bar` is not implemented for `{float}` - | | - | required by a bound introduced by this call - | - = help: the following other types implement trait `Bar`: - i32 - u32 -note: required by a bound in `only_bar` - --> $DIR/type_inference.rs:12:16 - | -LL | fn only_bar(_x: T) { } - | ^^^ required by this bound in `only_bar` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/chalkify/type_wf.rs b/tests/ui/chalkify/type_wf.rs deleted file mode 100644 index 37d2f5ca832..00000000000 --- a/tests/ui/chalkify/type_wf.rs +++ /dev/null @@ -1,25 +0,0 @@ -// check-fail -// compile-flags: -Z trait-solver=chalk - -trait Foo { } - -struct S { - x: T, -} - -impl Foo for i32 { } -impl Foo for Option { } - -fn main() { - let s = S { - x: 5, - }; - - let s = S { - x: 5.0, //~ ERROR the trait bound `{float}: Foo` is not satisfied - }; - - let s = S { - x: Some(5.0), - }; -} diff --git a/tests/ui/chalkify/type_wf.stderr b/tests/ui/chalkify/type_wf.stderr deleted file mode 100644 index 6e8daf63517..00000000000 --- a/tests/ui/chalkify/type_wf.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error[E0277]: the trait bound `{float}: Foo` is not satisfied - --> $DIR/type_wf.rs:19:12 - | -LL | x: 5.0, - | ^^^ the trait `Foo` is not implemented for `{float}` - | - = help: the trait `Foo` is implemented for `i32` -note: required by a bound in `S` - --> $DIR/type_wf.rs:6:13 - | -LL | struct S { - | ^^^ required by this bound in `S` - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/impl-trait/issue-55872-3.stderr b/tests/ui/impl-trait/issue-55872-3.stderr index c6e10f0f350..82798897433 100644 --- a/tests/ui/impl-trait/issue-55872-3.stderr +++ b/tests/ui/impl-trait/issue-55872-3.stderr @@ -1,8 +1,8 @@ -error[E0277]: the trait bound `[async block@$DIR/issue-55872-3.rs:16:9: 16:17]: Copy` is not satisfied - --> $DIR/issue-55872-3.rs:14:20 +error[E0277]: the trait bound `[async block@$DIR/issue-55872-3.rs:15:9: 15:17]: Copy` is not satisfied + --> $DIR/issue-55872-3.rs:13:20 | LL | fn foo() -> Self::E { - | ^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/issue-55872-3.rs:16:9: 16:17]` + | ^^^^^^^ the trait `Copy` is not implemented for `[async block@$DIR/issue-55872-3.rs:15:9: 15:17]` error: aborting due to previous error From c6fcbaae0f11f3f7d7827f946e8ca9a44c1da3ef Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Jul 2023 15:22:00 +0000 Subject: [PATCH 2/3] Remove compare mode --- src/bootstrap/flags.rs | 2 +- src/tools/compiletest/src/common.rs | 1 - src/tools/compiletest/src/runtest.rs | 3 --- src/tools/tidy/src/deps.rs | 4 ---- tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs | 1 - tests/ui/impl-trait/issue-55872-3.rs | 1 - tests/ui/impl-trait/issues/issue-65581.rs | 1 - 7 files changed, 1 insertion(+), 12 deletions(-) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index dc05f47ee9c..a882336c3c4 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -304,7 +304,7 @@ pub enum Subcommand { ./x.py test library/std --test-args hash_map ./x.py test library/std --stage 0 --no-doc ./x.py test tests/ui --bless - ./x.py test tests/ui --compare-mode chalk + ./x.py test tests/ui --compare-mode next-solver Note that `test tests/* --stage N` does NOT depend on `build compiler/rustc --stage N`; just like `build library/std --stage N` it tests the compiler produced by the previous stage. diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index c95a125c737..7c17e92d0df 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -107,7 +107,6 @@ string_enum! { #[derive(Clone, Debug, PartialEq)] pub enum CompareMode { Polonius => "polonius", - Chalk => "chalk", NextSolver => "next-solver", NextSolverCoherence => "next-solver-coherence", SplitDwarf => "split-dwarf", diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index fddfbac78d5..e8d0ebd40b0 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2435,9 +2435,6 @@ impl<'test> TestCx<'test> { Some(CompareMode::Polonius) => { rustc.args(&["-Zpolonius"]); } - Some(CompareMode::Chalk) => { - rustc.args(&["-Ztrait-solver=chalk"]); - } Some(CompareMode::NextSolver) => { rustc.args(&["-Ztrait-solver=next"]); } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index a70ffc3e798..1f6c0b75a09 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -122,10 +122,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[ "byteorder", // via ruzstd in object in thorin-dwp "cc", "cfg-if", - "chalk-derive", - "chalk-engine", - "chalk-ir", - "chalk-solve", "compiler_builtins", "convert_case", // dependency of derive_more "cpufeatures", diff --git a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs index 6dfd7f6840f..0d019b1f502 100644 --- a/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs +++ b/tests/ui/feature-gates/feature-gate-type_alias_impl_trait.rs @@ -1,4 +1,3 @@ -// ignore-compare-mode-chalk // check-pass #![feature(type_alias_impl_trait)] use std::fmt::Debug; diff --git a/tests/ui/impl-trait/issue-55872-3.rs b/tests/ui/impl-trait/issue-55872-3.rs index d031271ac08..7490a130800 100644 --- a/tests/ui/impl-trait/issue-55872-3.rs +++ b/tests/ui/impl-trait/issue-55872-3.rs @@ -1,5 +1,4 @@ // edition:2018 -// ignore-compare-mode-chalk #![feature(impl_trait_in_assoc_type)] diff --git a/tests/ui/impl-trait/issues/issue-65581.rs b/tests/ui/impl-trait/issues/issue-65581.rs index b947fc1d239..af65b79d3e8 100644 --- a/tests/ui/impl-trait/issues/issue-65581.rs +++ b/tests/ui/impl-trait/issues/issue-65581.rs @@ -1,5 +1,4 @@ // check-pass -// ignore-compare-mode-chalk #![allow(dead_code)] From 0c73b41cd69c33b76ba2a833bf8bd94a95e73ccb Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 3 Jul 2023 15:27:41 +0000 Subject: [PATCH 3/3] remove TypeWellFormedFromEnv --- compiler/rustc_hir_analysis/src/astconv/mod.rs | 3 +-- .../src/impl_wf_check/min_specialization.rs | 3 +-- .../rustc_hir_analysis/src/outlives/explicit.rs | 3 +-- compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 3 +-- compiler/rustc_infer/src/infer/outlives/mod.rs | 3 +-- compiler/rustc_infer/src/traits/util.rs | 3 --- compiler/rustc_lint/src/builtin.rs | 3 +-- compiler/rustc_middle/src/ty/flags.rs | 3 --- compiler/rustc_middle/src/ty/mod.rs | 17 ++++------------- compiler/rustc_middle/src/ty/print/pretty.rs | 3 --- .../rustc_middle/src/ty/structural_impls.rs | 3 --- compiler/rustc_privacy/src/lib.rs | 1 - .../src/solve/eval_ctxt.rs | 3 --- .../src/traits/auto_trait.rs | 3 --- .../src/traits/error_reporting/mod.rs | 7 ------- .../rustc_trait_selection/src/traits/fulfill.rs | 6 ------ .../src/traits/object_safety.rs | 5 ++--- .../query/type_op/implied_outlives_bounds.rs | 2 +- .../src/traits/select/mod.rs | 3 --- compiler/rustc_trait_selection/src/traits/wf.rs | 6 ++---- .../src/normalize_erasing_regions.rs | 3 +-- src/librustdoc/clean/mod.rs | 3 +-- 23 files changed, 18 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 9b5ff3240ed..1d5e4ac55f8 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -983,8 +983,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ty::ClauseKind::RegionOutlives(_) | ty::ClauseKind::ConstArgHasType(..) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::TypeWellFormedFromEnv(_) => { + | ty::ClauseKind::ConstEvaluatable(_) => { bug!() } } diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs index 67800dbd2a2..c64fb469bb2 100644 --- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs +++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs @@ -551,7 +551,6 @@ fn trait_predicate_kind<'tcx>( | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => None, + | ty::PredicateKind::Ambiguous => None, } } diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs index 3a04c3336ca..a7fca41f86a 100644 --- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs +++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs @@ -53,8 +53,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::TypeWellFormedFromEnv(_) => {} + | ty::ClauseKind::ConstEvaluatable(_) => {} } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index d9d91b0f6be..adf1b8e351f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -685,7 +685,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // inference variable. | ty::PredicateKind::ClosureKind(..) | ty::PredicateKind::Ambiguous - | ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => None, + => None, }, ) } diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 4c41fa38012..5e28ad5fd58 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -847,8 +847,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::TypeWellFormedFromEnv(_) => None, + | ty::ClauseKind::ConstEvaluatable(_) => None, } }); diff --git a/compiler/rustc_infer/src/infer/outlives/mod.rs b/compiler/rustc_infer/src/infer/outlives/mod.rs index c998c923760..cb92fc6ddb6 100644 --- a/compiler/rustc_infer/src/infer/outlives/mod.rs +++ b/compiler/rustc_infer/src/infer/outlives/mod.rs @@ -31,8 +31,7 @@ pub fn explicit_outlives_bounds<'tcx>( | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::TypeWellFormedFromEnv(_) => None, + | ty::ClauseKind::ConstEvaluatable(_) => None, }) } diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs index 66389cf5995..3aeed93baf2 100644 --- a/compiler/rustc_infer/src/traits/util.rs +++ b/compiler/rustc_infer/src/traits/util.rs @@ -370,9 +370,6 @@ impl<'tcx, O: Elaboratable<'tcx>> Elaborator<'tcx, O> { }), ); } - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - // Nothing to elaborate - } ty::PredicateKind::Ambiguous => {} ty::PredicateKind::AliasRelate(..) => { // No diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 3a177038ca8..c24760263bf 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -1606,8 +1606,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints { // Ignore bounds that a user can't type | ClauseKind::WellFormed(..) // FIXME(generic_const_exprs): `ConstEvaluatable` can be written - | ClauseKind::ConstEvaluatable(..) - | ClauseKind::TypeWellFormedFromEnv(_) => continue, + | ClauseKind::ConstEvaluatable(..) => continue, }; if predicate.is_global() { cx.emit_spanned_lint( diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 06a8e34cbab..ff391794703 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -287,9 +287,6 @@ impl FlagComputation { self.add_const(expected); self.add_const(found); } - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(ty)) => { - self.add_ty(ty); - } ty::PredicateKind::Ambiguous => {} ty::PredicateKind::AliasRelate(t1, t2, _) => { self.add_term(t1); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 7bd49ad07ea..48388be2f46 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -554,8 +554,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Coerce(_) | PredicateKind::Clause(ClauseKind::ConstEvaluatable(_)) | PredicateKind::ConstEquate(_, _) - | PredicateKind::Ambiguous - | PredicateKind::Clause(ClauseKind::TypeWellFormedFromEnv(_)) => true, + | PredicateKind::Ambiguous => true, } } } @@ -661,11 +660,6 @@ pub enum ClauseKind<'tcx> { /// Constant initializer must evaluate successfully. ConstEvaluatable(ty::Const<'tcx>), - - /// Represents a type found in the environment that we can use for implied bounds. - /// - /// Only used for Chalk. - TypeWellFormedFromEnv(Ty<'tcx>), } #[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)] @@ -1424,8 +1418,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Clause(ClauseKind::TypeOutlives(..)) | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..)) | PredicateKind::ConstEquate(..) - | PredicateKind::Ambiguous - | PredicateKind::Clause(ClauseKind::TypeWellFormedFromEnv(..)) => None, + | PredicateKind::Ambiguous => None, } } @@ -1445,8 +1438,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::Clause(ClauseKind::TypeOutlives(..)) | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..)) | PredicateKind::ConstEquate(..) - | PredicateKind::Ambiguous - | PredicateKind::Clause(ClauseKind::TypeWellFormedFromEnv(..)) => None, + | PredicateKind::Ambiguous => None, } } @@ -1466,8 +1458,7 @@ impl<'tcx> Predicate<'tcx> { | PredicateKind::ClosureKind(..) | PredicateKind::Clause(ClauseKind::ConstEvaluatable(..)) | PredicateKind::ConstEquate(..) - | PredicateKind::Ambiguous - | PredicateKind::Clause(ClauseKind::TypeWellFormedFromEnv(..)) => None, + | PredicateKind::Ambiguous => None, } } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index dcc8247937d..f912ff04496 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -2888,9 +2888,6 @@ define_print_and_forward_display! { ty::ClauseKind::ConstEvaluatable(ct) => { p!("the constant `", print(ct), "` can be evaluated") } - ty::ClauseKind::TypeWellFormedFromEnv(ty) => { - p!("the type `", print(ty), "` is found in the environment") - } } } diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 113328de176..f195b062a62 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -189,9 +189,6 @@ impl<'tcx> fmt::Debug for ty::ClauseKind<'tcx> { ty::ClauseKind::ConstEvaluatable(ct) => { write!(f, "ConstEvaluatable({ct:?})") } - ty::ClauseKind::TypeWellFormedFromEnv(ty) => { - write!(f, "TypeWellFormedFromEnv({:?})", ty) - } } } } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 055006373ef..4fcee9396ed 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -174,7 +174,6 @@ where } ty::ClauseKind::ConstEvaluatable(ct) => ct.visit_with(self), ty::ClauseKind::WellFormed(arg) => arg.visit_with(self), - ty::ClauseKind::TypeWellFormedFromEnv(_) => bug!("unexpected clause: {clause}"), } } diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs index 3b0c5849099..6b7be73b631 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs @@ -435,9 +435,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> { ty::PredicateKind::ConstEquate(_, _) => { bug!("ConstEquate should not be emitted when `-Ztrait-solver=next` is active") } - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - bug!("TypeWellFormedFromEnv is only used for Chalk") - } ty::PredicateKind::AliasRelate(lhs, rhs, direction) => self .compute_alias_relate_goal(Goal { param_env, diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs index fb6bf7211b9..cb42281152d 100644 --- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs +++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs @@ -836,9 +836,6 @@ impl<'tcx> AutoTraitFinder<'tcx> { // FIXME(generic_const_exprs): you can absolutely add this as a where clauses | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::Coerce(..) => {} - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - bug!("predicate should only exist in the environment: {bound_predicate:?}") - } ty::PredicateKind::Ambiguous => return false, }; } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index cddfb15869f..5fff645dd22 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1094,13 +1094,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Ambiguous => span_bug!(span, "ambiguous"), - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - span_bug!( - span, - "TypeWellFormedFromEnv predicate should only exist in the environment" - ) - } - ty::PredicateKind::AliasRelate(..) => span_bug!( span, "AliasRelate predicate should never be the predicate cause of a SelectionError" diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs index e3472a1c4c1..3d96c422256 100644 --- a/compiler/rustc_trait_selection/src/traits/fulfill.rs +++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs @@ -359,9 +359,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { ProcessResult::Changed(mk_pending(vec![obligation.with(infcx.tcx, pred)])) } ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - bug!("TypeWellFormedFromEnv is only used for Chalk") - } ty::PredicateKind::AliasRelate(..) => { bug!("AliasRelate is only used for new solver") } @@ -627,9 +624,6 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> { } } ty::PredicateKind::Ambiguous => ProcessResult::Unchanged, - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - bug!("TypeWellFormedFromEnv is only used for Chalk") - } ty::PredicateKind::AliasRelate(..) => { bug!("AliasRelate is only used for new solver") } diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 78270b7d535..08be60c65d4 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -311,7 +311,7 @@ fn predicate_references_self<'tcx>( | ty::ClauseKind::RegionOutlives(..) // FIXME(generic_const_exprs): this can mention `Self` | ty::ClauseKind::ConstEvaluatable(..) - | ty::ClauseKind::TypeWellFormedFromEnv(_) => None, + => None, } } @@ -351,8 +351,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool { | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::TypeWellFormedFromEnv(_) => false, + | ty::ClauseKind::ConstEvaluatable(_) => false, }) } diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 83d536c9ca5..42c2c37eca2 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -134,7 +134,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>( | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => {} + => {} // We need to search through *all* WellFormed predicates ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => { diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index c12d92b9012..eb11163de42 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -972,9 +972,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } } } - ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { - bug!("TypeWellFormedFromEnv is only used for chalk") - } ty::PredicateKind::AliasRelate(..) => { bug!("AliasRelate is only used for new solver") } diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 8bb4288f80d..86c7fc45ff7 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -184,8 +184,7 @@ pub fn predicate_obligations<'tcx>( | ty::PredicateKind::Coerce(..) | ty::PredicateKind::ConstEquate(..) | ty::PredicateKind::Ambiguous - | ty::PredicateKind::AliasRelate(..) - | ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => { + | ty::PredicateKind::AliasRelate(..) => { bug!("We should only wf check where clauses, unexpected predicate: {predicate:?}") } } @@ -1005,8 +1004,7 @@ pub(crate) fn required_region_bounds<'tcx>( | ty::ClauseKind::Projection(_) | ty::ClauseKind::ConstArgHasType(_, _) | ty::ClauseKind::WellFormed(_) - | ty::ClauseKind::ConstEvaluatable(_) - | ty::ClauseKind::TypeWellFormedFromEnv(_) => None, + | ty::ClauseKind::ConstEvaluatable(_) => None, } }) .collect() diff --git a/compiler/rustc_traits/src/normalize_erasing_regions.rs b/compiler/rustc_traits/src/normalize_erasing_regions.rs index b83abf98592..2563e3ed1a3 100644 --- a/compiler/rustc_traits/src/normalize_erasing_regions.rs +++ b/compiler/rustc_traits/src/normalize_erasing_regions.rs @@ -69,7 +69,6 @@ fn not_outlives_predicate(p: ty::Predicate<'_>) -> bool { | ty::PredicateKind::Coerce(..) | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..)) | ty::PredicateKind::ConstEquate(..) - | ty::PredicateKind::Ambiguous - | ty::PredicateKind::Clause(ty::ClauseKind::TypeWellFormedFromEnv(..)) => true, + | ty::PredicateKind::Ambiguous => true, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index b2f9c0bccea..0182d50773d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -342,8 +342,7 @@ pub(crate) fn clean_predicate<'tcx>( // FIXME(generic_const_exprs): should this do something? ty::ClauseKind::ConstEvaluatable(..) | ty::ClauseKind::WellFormed(..) - | ty::ClauseKind::ConstArgHasType(..) - | ty::ClauseKind::TypeWellFormedFromEnv(..) => None, + | ty::ClauseKind::ConstArgHasType(..) => None, } }