From a9e453ecb33d86efb2398971791b9b9a9e6f931c Mon Sep 17 00:00:00 2001 From: kadmin Date: Tue, 8 Feb 2022 17:27:11 +0000 Subject: [PATCH 01/14] Initial changes to rename proj type to term This just changes the name of projection type to term, which highlights where other changes to using a term should go. --- chalk-engine/src/slg.rs | 12 +++++----- chalk-engine/src/slg/aggregate.rs | 18 +++++++------- chalk-integration/src/db.rs | 6 ++--- chalk-integration/src/interner.rs | 8 +++---- chalk-integration/src/lowering.rs | 10 ++++---- chalk-integration/src/lowering/env.rs | 2 +- .../src/lowering/program_lowerer.rs | 4 ++-- chalk-integration/src/program.rs | 16 ++++++------- chalk-integration/src/test_macros.rs | 4 ++-- chalk-integration/src/tls.rs | 8 +++---- chalk-ir/src/debug.rs | 20 ++++++++-------- chalk-ir/src/fold/boring_impls.rs | 2 +- chalk-ir/src/interner.rs | 10 ++++---- chalk-ir/src/lib.rs | 14 +++++------ chalk-ir/src/visit/boring_impls.rs | 4 ++-- chalk-ir/src/zip.rs | 11 ++++++--- chalk-parse/src/ast.rs | 8 +++---- chalk-parse/src/parser.lalrpop | 12 +++++----- chalk-solve/src/clauses.rs | 24 +++++++++---------- .../builtin_traits/discriminant_kind.rs | 6 ++--- .../src/clauses/builtin_traits/fn_family.rs | 6 ++--- .../src/clauses/builtin_traits/generator.rs | 10 ++++---- chalk-solve/src/clauses/program_clauses.rs | 4 ++-- chalk-solve/src/display/identifiers.rs | 2 +- chalk-solve/src/display/stub.rs | 4 ++-- chalk-solve/src/display/ty.rs | 2 +- chalk-solve/src/infer/unify.rs | 8 +++---- chalk-solve/src/lib.rs | 4 ++-- chalk-solve/src/logging_db.rs | 8 +++---- chalk-solve/src/logging_db/id_collector.rs | 2 +- chalk-solve/src/rust_ir.rs | 20 ++++++++-------- chalk-solve/src/split.rs | 18 +++++++------- chalk-solve/src/wf.rs | 2 +- tests/display/unique_names.rs | 4 ++-- tests/integration/panic.rs | 2 +- tests/test/type_flags.rs | 4 ++-- 36 files changed, 152 insertions(+), 147 deletions(-) diff --git a/chalk-engine/src/slg.rs b/chalk-engine/src/slg.rs index f3522e77765..057133a3dc1 100644 --- a/chalk-engine/src/slg.rs +++ b/chalk-engine/src/slg.rs @@ -306,15 +306,15 @@ impl MayInvalidate { fn aggregate_projection_tys( &mut self, - new: &ProjectionTy, - current: &ProjectionTy, + new: &ProjectionTerm, + current: &ProjectionTerm, ) -> bool { - let ProjectionTy { - associated_ty_id: new_name, + let ProjectionTerm { + associated_term_id: new_name, substitution: new_substitution, } = new; - let ProjectionTy { - associated_ty_id: current_name, + let ProjectionTerm { + associated_term_id: current_name, substitution: current_substitution, } = current; diff --git a/chalk-engine/src/slg/aggregate.rs b/chalk-engine/src/slg/aggregate.rs index cce4e14dd61..761709a261c 100644 --- a/chalk-engine/src/slg/aggregate.rs +++ b/chalk-engine/src/slg/aggregate.rs @@ -382,23 +382,23 @@ impl AntiUnifier<'_, I> { fn aggregate_projection_tys( &mut self, - proj1: &ProjectionTy, - proj2: &ProjectionTy, + proj1: &ProjectionTerm, + proj2: &ProjectionTerm, ) -> Ty { let interner = self.interner; - let ProjectionTy { - associated_ty_id: name1, + let ProjectionTerm { + associated_term_id: name1, substitution: substitution1, } = proj1; - let ProjectionTy { - associated_ty_id: name2, + let ProjectionTerm { + associated_term_id: name2, substitution: substitution2, } = proj2; self.aggregate_name_and_substs(name1, substitution1, name2, substitution2) - .map(|(&associated_ty_id, substitution)| { - TyKind::Alias(AliasTy::Projection(ProjectionTy { - associated_ty_id, + .map(|(&associated_term_id, substitution)| { + TyKind::Alias(AliasTy::Projection(ProjectionTerm { + associated_term_id, substitution, })) .intern(interner) diff --git a/chalk-integration/src/db.rs b/chalk-integration/src/db.rs index fda52182653..c62e5c7fb79 100644 --- a/chalk-integration/src/db.rs +++ b/chalk-integration/src/db.rs @@ -7,7 +7,7 @@ use crate::{ tls, SolverChoice, }; use chalk_ir::{ - AdtId, AssocTypeId, Binders, Canonical, CanonicalVarKinds, ClosureId, ConstrainedSubst, + AdtId, AssocItemId, Binders, Canonical, CanonicalVarKinds, ClosureId, ConstrainedSubst, Environment, FnDefId, GeneratorId, GenericArg, Goal, ImplId, InEnvironment, OpaqueTyId, ProgramClause, ProgramClauses, Substitution, TraitId, Ty, TyKind, UCanonical, UnificationDatabase, Variances, @@ -87,7 +87,7 @@ impl RustIrDatabase for ChalkDatabase { self.program_ir().unwrap().custom_clauses() } - fn associated_ty_data(&self, ty: AssocTypeId) -> Arc> { + fn associated_ty_data(&self, ty: AssocItemId) -> Arc> { self.program_ir().unwrap().associated_ty_data(ty) } @@ -235,7 +235,7 @@ impl RustIrDatabase for ChalkDatabase { self.program_ir().unwrap().adt_name(struct_id) } - fn assoc_type_name(&self, assoc_ty_id: AssocTypeId) -> String { + fn assoc_type_name(&self, assoc_ty_id: AssocItemId) -> String { self.program_ir().unwrap().assoc_type_name(assoc_ty_id) } diff --git a/chalk-integration/src/interner.rs b/chalk-integration/src/interner.rs index cef01c2cd42..e026fcd8e83 100644 --- a/chalk-integration/src/interner.rs +++ b/chalk-integration/src/interner.rs @@ -4,9 +4,9 @@ use chalk_ir::{ TyKind, }; use chalk_ir::{ - AdtId, AliasTy, AssocTypeId, CanonicalVarKind, CanonicalVarKinds, ConstData, Constraint, + AdtId, AliasTy, AssocItemId, CanonicalVarKind, CanonicalVarKinds, ConstData, Constraint, Constraints, FnDefId, Goals, InEnvironment, Lifetime, OpaqueTy, OpaqueTyId, - ProgramClauseImplication, ProgramClauses, ProjectionTy, QuantifiedWhereClauses, + ProgramClauseImplication, ProgramClauses, ProjectionTerm, QuantifiedWhereClauses, SeparatorTraitRef, Substitution, TraitId, Ty, TyData, VariableKind, VariableKinds, Variances, }; use chalk_ir::{ @@ -91,7 +91,7 @@ impl Interner for ChalkIr { } fn debug_assoc_type_id( - id: AssocTypeId, + id: AssocItemId, fmt: &mut fmt::Formatter<'_>, ) -> Option { tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt))) @@ -113,7 +113,7 @@ impl Interner for ChalkIr { } fn debug_projection_ty( - proj: &ProjectionTy, + proj: &ProjectionTerm, fmt: &mut fmt::Formatter<'_>, ) -> Option { tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt))) diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index 425534d535e..a337ab45ecf 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -618,11 +618,11 @@ impl Lower for TraitFlags { } } -impl LowerWithEnv for ProjectionTy { - type Lowered = chalk_ir::ProjectionTy; +impl LowerWithEnv for ProjectionTerm { + type Lowered = chalk_ir::ProjectionTerm; fn lower(&self, env: &Env) -> LowerResult { - let ProjectionTy { + let ProjectionTerm { ref trait_ref, ref name, ref args, @@ -658,8 +658,8 @@ impl LowerWithEnv for ProjectionTy { args.extend(trait_substitution.iter(interner).cloned()); - Ok(chalk_ir::ProjectionTy { - associated_ty_id: lookup.id, + Ok(chalk_ir::ProjectionTerm { + associated_term_id: lookup.id, substitution: chalk_ir::Substitution::from_iter(interner, args), }) } diff --git a/chalk-integration/src/lowering/env.rs b/chalk-integration/src/lowering/env.rs index 63e27a51f63..b585d26dfc4 100644 --- a/chalk-integration/src/lowering/env.rs +++ b/chalk-integration/src/lowering/env.rs @@ -71,7 +71,7 @@ pub struct Env<'k> { /// ``` #[derive(Debug, PartialEq, Eq)] pub struct AssociatedTyLookup { - pub id: chalk_ir::AssocTypeId, + pub id: chalk_ir::AssocItemId, pub addl_variable_kinds: Vec>, } diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index 187ded13d9e..f579ab44776 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -1,6 +1,6 @@ use chalk_ir::cast::Cast; use chalk_ir::{ - self, AdtId, AssocTypeId, BoundVar, ClosureId, DebruijnIndex, FnDefId, ForeignDefId, + self, AdtId, AssocItemId, BoundVar, ClosureId, DebruijnIndex, FnDefId, ForeignDefId, GeneratorId, ImplId, OpaqueTyId, TraitId, TyVariableKind, VariableKinds, }; use chalk_parse::ast::*; @@ -64,7 +64,7 @@ impl ProgramLowerer { for defn in &d.assoc_ty_defns { let addl_variable_kinds = defn.all_parameters(); let lookup = AssociatedTyLookup { - id: AssocTypeId(self.next_item_id()), + id: AssocItemId(self.next_item_id()), addl_variable_kinds: addl_variable_kinds.anonymize(), }; self.associated_ty_lookups diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index b82bd9db99e..84de2c75744 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -3,9 +3,9 @@ use crate::{tls, Identifier, TypeKind}; use chalk_ir::{could_match::CouldMatch, UnificationDatabase}; use chalk_ir::{debug::Angle, Variance}; use chalk_ir::{ - debug::SeparatorTraitRef, AdtId, AliasTy, AssocTypeId, Binders, CanonicalVarKinds, ClosureId, + debug::SeparatorTraitRef, AdtId, AliasTy, AssocItemId, Binders, CanonicalVarKinds, ClosureId, FnDefId, ForeignDefId, GeneratorId, GenericArg, Goal, Goals, ImplId, IntTy, Lifetime, OpaqueTy, - OpaqueTyId, ProgramClause, ProgramClauseImplication, ProgramClauses, ProjectionTy, Scalar, + OpaqueTyId, ProgramClause, ProgramClauseImplication, ProgramClauses, ProjectionTerm, Scalar, Substitution, TraitId, Ty, TyKind, UintTy, Variances, }; use chalk_solve::rust_ir::{ @@ -97,7 +97,7 @@ pub struct Program { pub well_known_traits: BTreeMap>, /// For each associated ty declaration `type Foo` found in a trait: - pub associated_ty_data: BTreeMap, Arc>>, + pub associated_ty_data: BTreeMap, Arc>>, /// For each user-specified clause pub custom_clauses: Vec>, @@ -151,13 +151,13 @@ impl tls::DebugContext for Program { fn debug_assoc_type_id( &self, - assoc_type_id: AssocTypeId, + assoc_type_id: AssocItemId, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error> { if let Some(d) = self.associated_ty_data.get(&assoc_type_id) { write!(fmt, "({:?}::{})", d.trait_id, d.name) } else { - fmt.debug_struct("InvalidAssocTypeId") + fmt.debug_struct("InvalidAssocItemId") .field("index", &assoc_type_id.0) .finish() } @@ -204,7 +204,7 @@ impl tls::DebugContext for Program { fn debug_projection_ty( &self, - projection_ty: &ProjectionTy, + projection_ty: &ProjectionTerm, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error> { let (associated_ty_data, trait_params, other_params) = self.split_projection(projection_ty); @@ -386,7 +386,7 @@ impl RustIrDatabase for Program { self.custom_clauses.clone() } - fn associated_ty_data(&self, ty: AssocTypeId) -> Arc> { + fn associated_ty_data(&self, ty: AssocItemId) -> Arc> { self.associated_ty_data[&ty].clone() } @@ -587,7 +587,7 @@ impl RustIrDatabase for Program { // normally acceptable, but causes the re-parse tests for the .chalk syntax // writer to fail. This is because they use the `Eq` implementation on // Program, which checks for name equality. - fn assoc_type_name(&self, assoc_type_id: AssocTypeId) -> String { + fn assoc_type_name(&self, assoc_type_id: AssocItemId) -> String { self.associated_ty_data .get(&assoc_type_id) .unwrap() diff --git a/chalk-integration/src/test_macros.rs b/chalk-integration/src/test_macros.rs index 96bfeb0d61e..305c7f615b7 100644 --- a/chalk-integration/src/test_macros.rs +++ b/chalk-integration/src/test_macros.rs @@ -39,8 +39,8 @@ macro_rules! ty { }; (projection (item $n:tt) $($arg:tt)*) => { - chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy { - associated_ty_id: AssocTypeId(chalk_integration::interner::RawId { index: $n }), + chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTerm { + associated_term_id: AssocItemId(chalk_integration::interner::RawId { index: $n }), substitution: chalk_ir::Substitution::from_iter( chalk_integration::interner::ChalkIr, vec![$(arg!($arg)),*] as Vec> diff --git a/chalk-integration/src/tls.rs b/chalk-integration/src/tls.rs index 58b1da3dfa8..f7bf22ae3e1 100644 --- a/chalk-integration/src/tls.rs +++ b/chalk-integration/src/tls.rs @@ -1,8 +1,8 @@ use crate::interner::ChalkIr; use chalk_ir::{ - debug::SeparatorTraitRef, AdtId, AliasTy, AssocTypeId, CanonicalVarKinds, Constraints, FnDefId, + debug::SeparatorTraitRef, AdtId, AliasTy, AssocItemId, CanonicalVarKinds, Constraints, FnDefId, GenericArg, Goal, Goals, Lifetime, OpaqueTy, OpaqueTyId, ProgramClause, - ProgramClauseImplication, ProgramClauses, ProjectionTy, QuantifiedWhereClauses, Substitution, + ProgramClauseImplication, ProgramClauses, ProjectionTerm, QuantifiedWhereClauses, Substitution, TraitId, Ty, VariableKinds, Variances, }; use std::cell::RefCell; @@ -28,7 +28,7 @@ pub trait DebugContext { fn debug_assoc_type_id( &self, - id: AssocTypeId, + id: AssocItemId, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error>; @@ -58,7 +58,7 @@ pub trait DebugContext { fn debug_projection_ty( &self, - proj: &ProjectionTy, + proj: &ProjectionTerm, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error>; diff --git a/chalk-ir/src/debug.rs b/chalk-ir/src/debug.rs index 08a1be78a4b..10da316cce3 100644 --- a/chalk-ir/src/debug.rs +++ b/chalk-ir/src/debug.rs @@ -30,10 +30,10 @@ impl Debug for AdtId { } } -impl Debug for AssocTypeId { +impl Debug for AssocItemId { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_assoc_type_id(*self, fmt) - .unwrap_or_else(|| write!(fmt, "AssocTypeId({:?})", self.0)) + .unwrap_or_else(|| write!(fmt, "AssocItemId({:?})", self.0)) } } @@ -150,10 +150,10 @@ impl Debug for QuantifiedWhereClauses { } } -impl Debug for ProjectionTy { +impl Debug for ProjectionTerm { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_projection_ty(self, fmt).unwrap_or_else(|| { - unimplemented!("cannot format ProjectionTy without setting Program in tls") + unimplemented!("cannot format ProjectionTerm without setting Program in tls") }) } } @@ -694,30 +694,30 @@ impl Debug for TypeOutlives { /// Helper struct for showing debug output for projection types. pub struct ProjectionTyDebug<'a, I: Interner> { - projection_ty: &'a ProjectionTy, + projection_term: &'a ProjectionTerm, interner: I, } impl<'a, I: Interner> Debug for ProjectionTyDebug<'a, I> { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { let ProjectionTyDebug { - projection_ty, + projection_term, interner, } = self; write!( fmt, "({:?}){:?}", - projection_ty.associated_ty_id, - projection_ty.substitution.with_angle(*interner) + projection_term.associated_term_id, + projection_term.substitution.with_angle(*interner) ) } } -impl ProjectionTy { +impl ProjectionTerm { /// Show debug output for the projection type. pub fn debug(&self, interner: I) -> ProjectionTyDebug<'_, I> { ProjectionTyDebug { - projection_ty: self, + projection_term: self, interner, } } diff --git a/chalk-ir/src/fold/boring_impls.rs b/chalk-ir/src/fold/boring_impls.rs index 9210ecac8c9..5b8d5bca675 100644 --- a/chalk-ir/src/fold/boring_impls.rs +++ b/chalk-ir/src/fold/boring_impls.rs @@ -213,7 +213,7 @@ macro_rules! id_fold { id_fold!(ImplId); id_fold!(AdtId); id_fold!(TraitId); -id_fold!(AssocTypeId); +id_fold!(AssocItemId); id_fold!(OpaqueTyId); id_fold!(FnDefId); id_fold!(ClosureId); diff --git a/chalk-ir/src/interner.rs b/chalk-ir/src/interner.rs index 8a3f88cc4af..40988c67321 100644 --- a/chalk-ir/src/interner.rs +++ b/chalk-ir/src/interner.rs @@ -1,6 +1,6 @@ //! Encapsulates the concrete representation of core types such as types and goals. use crate::AliasTy; -use crate::AssocTypeId; +use crate::AssocItemId; use crate::CanonicalVarKind; use crate::CanonicalVarKinds; use crate::ClosureId; @@ -23,7 +23,7 @@ use crate::ProgramClause; use crate::ProgramClauseData; use crate::ProgramClauseImplication; use crate::ProgramClauses; -use crate::ProjectionTy; +use crate::ProjectionTerm; use crate::QuantifiedWhereClause; use crate::QuantifiedWhereClauses; use crate::SeparatorTraitRef; @@ -221,7 +221,7 @@ pub trait Interner: Debug + Copy + Eq + Hash + Sized { /// Returns `None` to fallback to the default debug output. #[allow(unused_variables)] fn debug_assoc_type_id( - type_id: AssocTypeId, + type_id: AssocItemId, fmt: &mut fmt::Formatter<'_>, ) -> Option { None @@ -289,11 +289,11 @@ pub trait Interner: Debug + Copy + Eq + Hash + Sized { None } - /// Prints the debug representation of a ProjectionTy. + /// Prints the debug representation of a ProjectionTerm. /// Returns `None` to fallback to the default debug output. #[allow(unused_variables)] fn debug_projection_ty( - projection_ty: &ProjectionTy, + projection_ty: &ProjectionTerm, fmt: &mut fmt::Formatter<'_>, ) -> Option { None diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index 9376a6563b0..4038c0211d0 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -382,7 +382,7 @@ pub struct ClauseId(pub I::DefId); /// /// [`associated_ty_data`]: ../chalk_solve/trait.RustIrDatabase.html#tymethod.associated_ty_data #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct AssocTypeId(pub I::DefId); +pub struct AssocItemId(pub I::DefId); /// Id for an opaque type. #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -582,7 +582,7 @@ pub enum TyKind { Adt(AdtId, Substitution), /// an associated type like `Iterator::Item`; see `AssociatedType` for details - AssociatedType(AssocTypeId, Substitution), + AssociatedType(AssocItemId, Substitution), /// a scalar type like `bool` or `u32` Scalar(Scalar), @@ -1604,7 +1604,7 @@ pub type CanonicalVarKind = WithKind; #[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner, Zip)] pub enum AliasTy { /// An associated type projection. - Projection(ProjectionTy), + Projection(ProjectionTerm), /// An opaque type. Opaque(OpaqueTy), } @@ -1632,16 +1632,16 @@ impl AliasTy { /// A projection `>::AssocItem`. #[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, HasInterner)] -pub struct ProjectionTy { +pub struct ProjectionTerm { /// The id for the associated type member. - pub associated_ty_id: AssocTypeId, + pub associated_term_id: AssocItemId, /// The substitution for the projection. pub substitution: Substitution, } -impl Copy for ProjectionTy where I::InternedSubstitution: Copy {} +impl Copy for ProjectionTerm where I::InternedSubstitution: Copy {} -impl ProjectionTy { +impl ProjectionTerm { /// Gets the type parameters of the `Self` type in this alias type. pub fn self_type_parameter(&self, interner: I) -> Ty { self.substitution diff --git a/chalk-ir/src/visit/boring_impls.rs b/chalk-ir/src/visit/boring_impls.rs index d4e52d15b35..36884306016 100644 --- a/chalk-ir/src/visit/boring_impls.rs +++ b/chalk-ir/src/visit/boring_impls.rs @@ -5,7 +5,7 @@ //! The more interesting impls of `Visit` remain in the `visit` module. use crate::{ - try_break, AdtId, AssocTypeId, ClausePriority, ClosureId, Constraints, ControlFlow, + try_break, AdtId, AssocItemId, ClausePriority, ClosureId, Constraints, ControlFlow, DebruijnIndex, FloatTy, FnDefId, ForeignDefId, GeneratorId, GenericArg, Goals, ImplId, IntTy, Interner, Mutability, OpaqueTyId, PlaceholderIndex, ProgramClause, ProgramClauses, QuantifiedWhereClauses, QuantifierKind, Safety, Scalar, Substitution, SuperVisit, TraitId, @@ -196,7 +196,7 @@ id_visit!(ImplId); id_visit!(AdtId); id_visit!(TraitId); id_visit!(OpaqueTyId); -id_visit!(AssocTypeId); +id_visit!(AssocItemId); id_visit!(FnDefId); id_visit!(ClosureId); id_visit!(GeneratorId); diff --git a/chalk-ir/src/zip.rs b/chalk-ir/src/zip.rs index f17a5f84bf2..5c71be20786 100644 --- a/chalk-ir/src/zip.rs +++ b/chalk-ir/src/zip.rs @@ -282,7 +282,7 @@ macro_rules! eq_zip { eq_zip!(I => AdtId); eq_zip!(I => TraitId); -eq_zip!(I => AssocTypeId); +eq_zip!(I => AssocItemId); eq_zip!(I => OpaqueTyId); eq_zip!(I => GeneratorId); eq_zip!(I => ForeignDefId); @@ -457,7 +457,7 @@ impl Zip for TraitRef { } } -impl Zip for ProjectionTy { +impl Zip for ProjectionTerm { fn zip_with>( zipper: &mut Z, variance: Variance, @@ -465,7 +465,12 @@ impl Zip for ProjectionTy { b: &Self, ) -> Fallible<()> { let interner = zipper.interner(); - Zip::zip_with(zipper, variance, &a.associated_ty_id, &b.associated_ty_id)?; + Zip::zip_with( + zipper, + variance, + &a.associated_term_id, + &b.associated_term_id, + )?; zipper.zip_substs( variance, None, diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index 3ed826479ad..bc56eeb099e 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -300,7 +300,7 @@ pub enum Ty { args: Vec, }, Projection { - proj: ProjectionTy, + proj: ProjectionTerm, }, ForAll { lifetime_names: Vec, @@ -395,7 +395,7 @@ pub enum Lifetime { } #[derive(Clone, PartialEq, Eq, Debug)] -pub struct ProjectionTy { +pub struct ProjectionTerm { pub trait_ref: TraitRef, pub name: Identifier, pub args: Vec, @@ -441,7 +441,7 @@ impl fmt::Display for Identifier { #[derive(Clone, PartialEq, Eq, Debug)] pub enum WhereClause { Implemented { trait_ref: TraitRef }, - ProjectionEq { projection: ProjectionTy, ty: Ty }, + ProjectionEq { projection: ProjectionTerm, ty: Ty }, LifetimeOutlives { a: Lifetime, b: Lifetime }, TypeOutlives { ty: Ty, lifetime: Lifetime }, } @@ -449,7 +449,7 @@ pub enum WhereClause { #[derive(Clone, PartialEq, Eq, Debug)] pub enum DomainGoal { Holds { where_clause: WhereClause }, - Normalize { projection: ProjectionTy, ty: Ty }, + Normalize { projection: ProjectionTerm, ty: Ty }, TraitRefWellFormed { trait_ref: TraitRef }, TyWellFormed { ty: Ty }, TyFromEnv { ty: Ty }, diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index 0eaa460facd..7ad7b84be41 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -429,7 +429,7 @@ TyWithoutId: Ty = { lifetime: l, }, "<" > ">" => Ty::Apply { name: n, args: a }, - => Ty::Projection { proj: p }, + => Ty::Projection { proj: p }, "(" ")" => t, "*" => Ty::Raw{ mutability: m, ty: Box::new(t) }, "&" "mut" => Ty::Ref{ mutability: Mutability::Mut, lifetime: l, ty: Box::new(t) }, @@ -467,7 +467,7 @@ FloatTy: FloatTy = { ScalarType: ScalarType = { => ScalarType::Int(i), => ScalarType::Uint(u), - => ScalarType::Float(f), + => ScalarType::Float(f), "bool" => ScalarType::Bool, "char" => ScalarType::Char, }; @@ -511,8 +511,8 @@ GenericArg: GenericArg = { ConstWithoutId => GenericArg::Const(<>), }; -ProjectionTy: ProjectionTy = { - "<" > ">" "::" > => ProjectionTy { +ProjectionTerm: ProjectionTerm = { + "<" > ">" "::" > => ProjectionTerm { trait_ref: t, name: n, args: a }, }; @@ -576,7 +576,7 @@ WhereClause: WhereClause = { let mut args = vec![GenericArg::Ty(s)]; if let Some(a) = a { args.extend(a); } let trait_ref = TraitRef { trait_name: t, args: args }; - let projection = ProjectionTy { trait_ref, name, args: a2 }; + let projection = ProjectionTerm { trait_ref, name, args: a2 }; WhereClause::ProjectionEq { projection, ty } }, @@ -620,7 +620,7 @@ DomainGoal: DomainGoal = { "FromEnv" "(" > ")" => DomainGoal::TraitRefFromEnv { trait_ref: t }, // `::U -> Bar` -- a normalization - "Normalize" "(" "->" ")" => DomainGoal::Normalize { projection: s, ty: t }, + "Normalize" "(" "->" ")" => DomainGoal::Normalize { projection: s, ty: t }, "IsLocal" "(" ")" => DomainGoal::IsLocal { ty }, "IsUpstream" "(" ")" => DomainGoal::IsUpstream { ty }, diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index e795c8fd63e..780f437f053 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -531,7 +531,7 @@ pub fn program_clauses_that_could_match( _ => {} } - db.associated_ty_data(proj.associated_ty_id) + db.associated_ty_data(proj.associated_term_id) .to_program_clauses(builder, environment) } AliasTy::Opaque(opaque_ty) => db @@ -599,7 +599,7 @@ pub fn program_clauses_that_could_match( // type Item = Bar; // <-- associated type value // } // ``` - let associated_ty_datum = db.associated_ty_data(proj.associated_ty_id); + let associated_ty_datum = db.associated_ty_data(proj.associated_term_id); let trait_id = associated_ty_datum.trait_id; let trait_parameters = db.trait_parameters_from_projection(proj); @@ -639,7 +639,7 @@ pub fn program_clauses_that_could_match( builder, interner, trait_id, - proj.associated_ty_id, + proj.associated_term_id, ); } } @@ -665,13 +665,13 @@ fn push_clauses_for_compatible_normalize( builder: &mut ClauseBuilder<'_, I>, interner: I, trait_id: TraitId, - associated_ty_id: AssocTypeId, + associated_ty_id: AssocItemId, ) { let trait_datum = db.trait_datum(trait_id); let trait_binders = trait_datum.binders.map_ref(|b| &b.where_clauses).cloned(); builder.push_binders(trait_binders, |builder, where_clauses| { - let projection = ProjectionTy { - associated_ty_id, + let projection = ProjectionTerm { + associated_term_id: associated_ty_id, substitution: builder.substitution_in_scope(), }; let trait_ref = TraitRef { @@ -797,7 +797,7 @@ fn push_alias_implemented_clause( fn push_alias_alias_eq_clause( builder: &mut ClauseBuilder<'_, I>, - projection_ty: ProjectionTy, + projection_ty: ProjectionTerm, ty: Ty, alias: AliasTy, ) { @@ -824,8 +824,8 @@ fn push_alias_alias_eq_clause( .cloned(), ), ); - let fresh_alias = AliasTy::Projection(ProjectionTy { - associated_ty_id: projection_ty.associated_ty_id, + let fresh_alias = AliasTy::Projection(ProjectionTerm { + associated_term_id: projection_ty.associated_term_id, substitution: fresh_self_subst, }); builder.push_clause( @@ -1033,7 +1033,7 @@ fn match_ty( } TyKind::Alias(AliasTy::Projection(proj)) => builder .db - .associated_ty_data(proj.associated_ty_id) + .associated_ty_data(proj.associated_term_id) .to_program_clauses(builder, environment), TyKind::Alias(AliasTy::Opaque(opaque_ty)) => builder .db @@ -1089,10 +1089,10 @@ fn match_alias_ty( environment: &Environment, alias: &AliasTy, ) { - if let AliasTy::Projection(projection_ty) = alias { + if let AliasTy::Projection(projection_term) = alias { builder .db - .associated_ty_data(projection_ty.associated_ty_id) + .associated_ty_data(projection_term.associated_term_id) .to_program_clauses(builder, environment) } } diff --git a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs index 27d49df7597..3cb440247a8 100644 --- a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs +++ b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs @@ -1,7 +1,7 @@ use crate::clauses::ClauseBuilder; use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait}; use chalk_ir::{ - AliasTy, Floundered, Normalize, ProjectionTy, Substitution, Ty, TyKind, TyVariableKind, + AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Ty, TyKind, TyVariableKind, }; pub fn add_discriminant_clauses( @@ -59,8 +59,8 @@ pub fn add_discriminant_clauses( }; let normalize = Normalize { - alias: AliasTy::Projection(ProjectionTy { - associated_ty_id, + alias: AliasTy::Projection(ProjectionTerm { + associated_term_id: associated_ty_id, substitution, }), ty: disc_ty, diff --git a/chalk-solve/src/clauses/builtin_traits/fn_family.rs b/chalk-solve/src/clauses/builtin_traits/fn_family.rs index f2358bc7300..9dace598f0e 100644 --- a/chalk-solve/src/clauses/builtin_traits/fn_family.rs +++ b/chalk-solve/src/clauses/builtin_traits/fn_family.rs @@ -3,7 +3,7 @@ use crate::rust_ir::{ClosureKind, FnDefInputsAndOutputDatum, WellKnownTrait}; use crate::{Interner, RustIrDatabase, TraitRef}; use chalk_ir::cast::Cast; use chalk_ir::{ - AliasTy, Binders, Normalize, ProjectionTy, Safety, Substitution, TraitId, Ty, TyKind, + AliasTy, Binders, Normalize, ProjectionTerm, Safety, Substitution, TraitId, Ty, TyKind, }; fn push_clauses( @@ -36,8 +36,8 @@ fn push_clauses( // Constructs the alias. For `Fn`, for example, this would look like // `Normalize( B as FnOnce<(A,)>>::Output -> B)` let output_id = trait_datum.associated_ty_ids[0]; - let alias = AliasTy::Projection(ProjectionTy { - associated_ty_id: output_id, + let alias = AliasTy::Projection(ProjectionTerm { + associated_term_id: output_id, substitution, }); builder.push_fact(Normalize { diff --git a/chalk-solve/src/clauses/builtin_traits/generator.rs b/chalk-solve/src/clauses/builtin_traits/generator.rs index 67415bfd76d..979614e7472 100644 --- a/chalk-solve/src/clauses/builtin_traits/generator.rs +++ b/chalk-solve/src/clauses/builtin_traits/generator.rs @@ -2,7 +2,7 @@ use crate::clauses::ClauseBuilder; use crate::rust_ir::WellKnownTrait; use crate::{Interner, RustIrDatabase, TraitRef}; use chalk_ir::cast::Cast; -use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTy, Substitution, Ty, TyKind}; +use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Ty, TyKind}; /// Add implicit impls of the generator trait, i.e., add a clause that all generators implement /// `Generator` and clauses for `Generator`'s associated types. @@ -46,8 +46,8 @@ pub fn add_generator_program_clauses( // `Generator::Yield` let yield_id = trait_datum.associated_ty_ids[0]; - let yield_alias = AliasTy::Projection(ProjectionTy { - associated_ty_id: yield_id, + let yield_alias = AliasTy::Projection(ProjectionTerm { + associated_term_id: yield_id, substitution: substitution.clone(), }); builder.push_fact(Normalize { @@ -57,8 +57,8 @@ pub fn add_generator_program_clauses( // `Generator::Return` let return_id = trait_datum.associated_ty_ids[1]; - let return_alias = AliasTy::Projection(ProjectionTy { - associated_ty_id: return_id, + let return_alias = AliasTy::Projection(ProjectionTerm { + associated_term_id: return_id, substitution, }); builder.push_fact(Normalize { diff --git a/chalk-solve/src/clauses/program_clauses.rs b/chalk-solve/src/clauses/program_clauses.rs index 19811ff8b30..ddba792871d 100644 --- a/chalk-solve/src/clauses/program_clauses.rs +++ b/chalk-solve/src/clauses/program_clauses.rs @@ -807,8 +807,8 @@ impl ToProgramClauses for AssociatedTyDatum { }| { let substitution = builder.substitution_in_scope(); - let projection = ProjectionTy { - associated_ty_id: self.id, + let projection = ProjectionTerm { + associated_term_id: self.id, substitution: substitution.clone(), }; let projection_ty = AliasTy::Projection(projection.clone()).intern(interner); diff --git a/chalk-solve/src/display/identifiers.rs b/chalk-solve/src/display/identifiers.rs index 81a08d71b30..1476a0cff43 100644 --- a/chalk-solve/src/display/identifiers.rs +++ b/chalk-solve/src/display/identifiers.rs @@ -31,7 +31,7 @@ impl RenderAsRust for TraitId { } } -impl RenderAsRust for AssocTypeId { +impl RenderAsRust for AssocItemId { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { // TODO: use debug methods? write!( diff --git a/chalk-solve/src/display/stub.rs b/chalk-solve/src/display/stub.rs index ec209bc91a0..7862a5c3463 100644 --- a/chalk-solve/src/display/stub.rs +++ b/chalk-solve/src/display/stub.rs @@ -43,7 +43,7 @@ impl> RustIrDatabase for StubWrapper<'_, D fn associated_ty_data( &self, - ty: chalk_ir::AssocTypeId, + ty: chalk_ir::AssocItemId, ) -> std::sync::Arc> { let mut v = (*self.db.associated_ty_data(ty)).clone(); v.binders = Binders::new( @@ -250,7 +250,7 @@ impl> RustIrDatabase for StubWrapper<'_, D self.db.adt_name(struct_id) } - fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocTypeId) -> String { + fn assoc_type_name(&self, assoc_ty_id: chalk_ir::AssocItemId) -> String { self.db.assoc_type_name(assoc_ty_id) } diff --git a/chalk-solve/src/display/ty.rs b/chalk-solve/src/display/ty.rs index 8012de5f5df..2f363663368 100644 --- a/chalk-solve/src/display/ty.rs +++ b/chalk-solve/src/display/ty.rs @@ -134,7 +134,7 @@ impl RenderAsRust for AliasTy { } } -impl RenderAsRust for ProjectionTy { +impl RenderAsRust for ProjectionTerm { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { // >::Z diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index e5e169fdc75..9c1782ea5ce 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -647,9 +647,9 @@ impl<'t, I: Interner> Unifier<'t, I> { }) } AliasTy::Projection(projection_ty) => { - let ProjectionTy { + let ProjectionTerm { ref substitution, - associated_ty_id, + associated_term_id, } = *projection_ty; // TODO: We should be skipping "self", which // would be the first element of @@ -662,9 +662,9 @@ impl<'t, I: Interner> Unifier<'t, I> { universe_index, |_| variance, ); - AliasTy::Projection(ProjectionTy { + AliasTy::Projection(ProjectionTerm { substitution, - associated_ty_id, + associated_term_id, }) } }; diff --git a/chalk-solve/src/lib.rs b/chalk-solve/src/lib.rs index a870a0c4961..d49c9960bfb 100644 --- a/chalk-solve/src/lib.rs +++ b/chalk-solve/src/lib.rs @@ -47,7 +47,7 @@ pub trait RustIrDatabase: Debug { fn custom_clauses(&self) -> Vec>; /// Returns the datum for the associated type with the given id. - fn associated_ty_data(&self, ty: AssocTypeId) -> Arc>; + fn associated_ty_data(&self, ty: AssocItemId) -> Arc>; /// Returns the datum for the definition with the given id. fn trait_datum(&self, trait_id: TraitId) -> Arc>; @@ -180,7 +180,7 @@ pub trait RustIrDatabase: Debug { /// Retrieves the name of an associated type. No uniqueness guarantees, but must /// a valid Rust identifier. - fn assoc_type_name(&self, assoc_ty_id: AssocTypeId) -> String { + fn assoc_type_name(&self, assoc_ty_id: AssocItemId) -> String { sanitize_debug_name(|f| I::debug_assoc_type_id(assoc_ty_id, f)) } diff --git a/chalk-solve/src/logging_db.rs b/chalk-solve/src/logging_db.rs index 12d8b052a2b..bc9d2377ff0 100644 --- a/chalk-solve/src/logging_db.rs +++ b/chalk-solve/src/logging_db.rs @@ -121,7 +121,7 @@ where fn associated_ty_data( &self, - ty: chalk_ir::AssocTypeId, + ty: chalk_ir::AssocItemId, ) -> Arc> { let ty_datum = self.ws.db().associated_ty_data(ty); self.record(ty_datum.trait_id); @@ -240,7 +240,7 @@ where self.ws.db().adt_name(adt_id) } - fn assoc_type_name(&self, assoc_ty_id: AssocTypeId) -> String { + fn assoc_type_name(&self, assoc_ty_id: AssocItemId) -> String { self.ws.db().assoc_type_name(assoc_ty_id) } @@ -397,7 +397,7 @@ where fn associated_ty_data( &self, - ty: chalk_ir::AssocTypeId, + ty: chalk_ir::AssocItemId, ) -> Arc> { self.db.associated_ty_data(ty) } @@ -500,7 +500,7 @@ where self.db.adt_name(adt_id) } - fn assoc_type_name(&self, assoc_ty_id: AssocTypeId) -> String { + fn assoc_type_name(&self, assoc_ty_id: AssocItemId) -> String { self.db.assoc_type_name(assoc_ty_id) } diff --git a/chalk-solve/src/logging_db/id_collector.rs b/chalk-solve/src/logging_db/id_collector.rs index 893652b70c4..5a0412f4d64 100644 --- a/chalk-solve/src/logging_db/id_collector.rs +++ b/chalk-solve/src/logging_db/id_collector.rs @@ -108,7 +108,7 @@ impl<'i, I: Interner, DB: RustIrDatabase> IdCollector<'i, I, DB> { fn visit_alias(&mut self, alias: &AliasTy) { match alias { AliasTy::Projection(projection_ty) => { - let assoc_ty_datum = self.db.associated_ty_data(projection_ty.associated_ty_id); + let assoc_ty_datum = self.db.associated_ty_data(projection_ty.associated_term_id); self.record(assoc_ty_datum.trait_id) } AliasTy::Opaque(opaque_ty) => self.record(opaque_ty.opaque_ty_id), diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index 7983b75f2e4..a55604d88e9 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -7,8 +7,8 @@ use chalk_ir::cast::Cast; use chalk_ir::fold::shift::Shift; use chalk_ir::interner::Interner; use chalk_ir::{ - try_break, visit::Visit, AdtId, AliasEq, AliasTy, AssocTypeId, Binders, DebruijnIndex, FnDefId, - GenericArg, ImplId, OpaqueTyId, ProjectionTy, QuantifiedWhereClause, Substitution, + try_break, visit::Visit, AdtId, AliasEq, AliasTy, AssocItemId, Binders, DebruijnIndex, FnDefId, + GenericArg, ImplId, OpaqueTyId, ProjectionTerm, QuantifiedWhereClause, Substitution, ToGenericArg, TraitId, TraitRef, Ty, TyKind, VariableKind, WhereClause, WithKind, }; use std::iter; @@ -249,7 +249,7 @@ pub struct TraitDatum { /// chalk we add annotations like `#[auto]`. pub flags: TraitFlags, - pub associated_ty_ids: Vec>, + pub associated_ty_ids: Vec>, /// If this is a well-known trait, which one? If `None`, this is a regular, /// user-defined trait. @@ -423,7 +423,7 @@ impl TraitBound { #[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)] pub struct AliasEqBound { pub trait_bound: TraitBound, - pub associated_ty_id: AssocTypeId, + pub associated_ty_id: AssocItemId, /// Does not include trait parameters. pub parameters: Vec>, pub value: Ty, @@ -444,8 +444,8 @@ impl AliasEqBound { vec![ WhereClause::Implemented(trait_ref), WhereClause::AliasEq(AliasEq { - alias: AliasTy::Projection(ProjectionTy { - associated_ty_id: self.associated_ty_id, + alias: AliasTy::Projection(ProjectionTerm { + associated_term_id: self.associated_ty_id, substitution, }), ty: self.value.clone(), @@ -490,7 +490,7 @@ pub struct AssociatedTyDatum { pub trait_id: TraitId, /// The ID of this associated type - pub id: AssocTypeId, + pub id: AssocItemId, /// Name of this associated type. pub name: I::Identifier, @@ -552,8 +552,8 @@ impl AssociatedTyDatum { ); // The self type will be `>::Item` etc - let self_ty = TyKind::Alias(AliasTy::Projection(ProjectionTy { - associated_ty_id: self.id, + let self_ty = TyKind::Alias(AliasTy::Projection(ProjectionTerm { + associated_term_id: self.id, substitution, })) .intern(interner); @@ -604,7 +604,7 @@ pub struct AssociatedTyValue { /// type Item; // <-- refers to this declaration here! /// } /// ``` - pub associated_ty_id: AssocTypeId, + pub associated_ty_id: AssocItemId, /// Additional binders declared on the associated type itself, /// beyond those from the impl. This would be empty for normal diff --git a/chalk-solve/src/split.rs b/chalk-solve/src/split.rs index bea24044db8..c286dc60985 100644 --- a/chalk-solve/src/split.rs +++ b/chalk-solve/src/split.rs @@ -16,19 +16,19 @@ pub trait Split: RustIrDatabase { /// any type parameters itself. fn split_projection<'p>( &self, - projection: &'p ProjectionTy, + projection: &'p ProjectionTerm, ) -> ( Arc>, &'p [GenericArg], &'p [GenericArg], ) { let interner = self.interner(); - let ProjectionTy { - associated_ty_id, + let ProjectionTerm { + associated_term_id, ref substitution, } = *projection; let parameters = substitution.as_slice(interner); - let associated_ty_data = &self.associated_ty_data(associated_ty_id); + let associated_ty_data = &self.associated_ty_data(associated_term_id); let (trait_params, other_params) = self.split_associated_ty_parameters(parameters, &**associated_ty_data); (associated_ty_data.clone(), trait_params, other_params) @@ -39,7 +39,7 @@ pub trait Split: RustIrDatabase { /// `split_projection`). fn trait_parameters_from_projection<'p>( &self, - projection: &'p ProjectionTy, + projection: &'p ProjectionTerm, ) -> &'p [GenericArg] { let (_, trait_params, _) = self.split_projection(projection); trait_params @@ -48,7 +48,7 @@ pub trait Split: RustIrDatabase { /// Given a projection `>::Item`, /// returns the trait parameters `[P0..Pn]` (see /// `split_projection`). - fn trait_ref_from_projection(&self, projection: &ProjectionTy) -> TraitRef { + fn trait_ref_from_projection(&self, projection: &ProjectionTerm) -> TraitRef { let interner = self.interner(); let (associated_ty_data, trait_params, _) = self.split_projection(projection); TraitRef { @@ -124,7 +124,7 @@ pub trait Split: RustIrDatabase { &self, parameters: &'p [GenericArg], associated_ty_value: &AssociatedTyValue, - ) -> (&'p [GenericArg], ProjectionTy) { + ) -> (&'p [GenericArg], ProjectionTerm) { let interner = self.interner(); let impl_datum = self.impl_datum(associated_ty_value.impl_id); @@ -150,8 +150,8 @@ pub trait Split: RustIrDatabase { .cloned(), ); - let projection = ProjectionTy { - associated_ty_id: associated_ty_value.associated_ty_id, + let projection = ProjectionTerm { + associated_term_id: associated_ty_value.associated_ty_id, substitution: projection_substitution, }; diff --git a/chalk-solve/src/wf.rs b/chalk-solve/src/wf.rs index 60d92860faa..58703753b4a 100644 --- a/chalk-solve/src/wf.rs +++ b/chalk-solve/src/wf.rs @@ -611,7 +611,7 @@ fn compute_assoc_ty_goal( // * where clauses // * original in trait, `Self: 'a` // * after substituting impl parameters, `Box: '!a` - let assoc_ty_datum = db.associated_ty_data(projection.associated_ty_id); + let assoc_ty_datum = db.associated_ty_data(projection.associated_term_id); let AssociatedTyDatumBound { bounds: defn_bounds, where_clauses: defn_where_clauses, diff --git a/tests/display/unique_names.rs b/tests/display/unique_names.rs index cd26f299ae3..6c1358a9594 100644 --- a/tests/display/unique_names.rs +++ b/tests/display/unique_names.rs @@ -46,7 +46,7 @@ where fn adt_name(&self, _adt_id: chalk_ir::AdtId) -> String { "Foo".to_owned() } - fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocTypeId) -> String { + fn assoc_type_name(&self, _assoc_ty_id: chalk_ir::AssocItemId) -> String { "Foo".to_owned() } fn opaque_type_name(&self, _opaque_ty_id: chalk_ir::OpaqueTyId) -> String { @@ -60,7 +60,7 @@ where } fn associated_ty_data( &self, - ty: chalk_ir::AssocTypeId, + ty: chalk_ir::AssocItemId, ) -> std::sync::Arc> { self.db.associated_ty_data(ty) } diff --git a/tests/integration/panic.rs b/tests/integration/panic.rs index d0cbfdb7c92..c42d61ae76d 100644 --- a/tests/integration/panic.rs +++ b/tests/integration/panic.rs @@ -54,7 +54,7 @@ impl RustIrDatabase for MockDatabase { vec![] } - fn associated_ty_data(&self, ty: AssocTypeId) -> Arc> { + fn associated_ty_data(&self, ty: AssocItemId) -> Arc> { unimplemented!() } diff --git a/tests/test/type_flags.rs b/tests/test/type_flags.rs index 5678781eab6..0575657f0df 100644 --- a/tests/test/type_flags.rs +++ b/tests/test/type_flags.rs @@ -45,8 +45,8 @@ fn opaque_ty_flags_correct() { #[test] fn dyn_ty_flags_correct() { let internal_ty = TyKind::Scalar(chalk_ir::Scalar::Bool).intern(ChalkIr); - let projection_ty = chalk_ir::ProjectionTy { - associated_ty_id: chalk_ir::AssocTypeId(chalk_integration::interner::RawId { index: 0 }), + let projection_ty = chalk_ir::ProjectionTerm { + associated_term_id: chalk_ir::AssocItemId(chalk_integration::interner::RawId { index: 0 }), substitution: empty_substitution!(), }; let bounds = chalk_ir::Binders::>::empty( From 7a4bd7fd9b6418d0421d096e742e4e3056da9bce Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 2 May 2022 02:23:50 +0000 Subject: [PATCH 02/14] Add associated consts to parsing --- chalk-parse/src/ast.rs | 7 +++++++ chalk-parse/src/parser.lalrpop | 12 +++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index bc56eeb099e..f5ec08d09c7 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -142,6 +142,7 @@ pub struct TraitDefn { pub variable_kinds: Vec, pub where_clauses: Vec, pub assoc_ty_defns: Vec, + pub assoc_const_defns: Vec, pub flags: TraitFlags, pub well_known: Option, } @@ -182,6 +183,12 @@ pub struct AssocTyDefn { pub where_clauses: Vec, } +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct AssocConstDefn { + pub name: Identifier, + pub ty: Ty, +} + #[derive(Clone, PartialEq, Eq, Debug)] pub struct OpaqueTyDefn { pub ty: Ty, diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index 7ad7b84be41..a148551e8e7 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -257,12 +257,13 @@ ClosureArgs: Vec = { TraitDefn: TraitDefn = { "trait" > - "{" "}" => TraitDefn + "{" "}" => TraitDefn { name: n, variable_kinds: p, where_clauses: w, assoc_ty_defns: a, + assoc_const_defns: ac, well_known, flags: TraitFlags { auto: auto.is_some(), @@ -289,6 +290,15 @@ AssocTyDefn: AssocTyDefn = { } }; +AssocConstDefn: AssocConstDefn = { + "const" ":" ";" => { + AssocConstDefn { + name: name, + ty: ty, + } + } +}; + OpaqueTyDefn: OpaqueTyDefn = { "opaque" "type" > >)?> "=" ";" => { From 8075c303886c7756c7333863f74e6318e499fa68 Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 2 May 2022 05:42:12 +0000 Subject: [PATCH 03/14] Continue adding associated consts --- chalk-integration/src/lowering.rs | 18 ++++++++-- chalk-integration/src/lowering/env.rs | 21 ++++++++++- .../src/lowering/program_lowerer.rs | 27 +++++++++++++- chalk-integration/src/program.rs | 5 +++ chalk-parse/src/ast.rs | 8 +++++ chalk-parse/src/parser.lalrpop | 11 +++++- chalk-solve/src/rust_ir.rs | 35 +++++++++++++++++++ tests/integration/panic.rs | 1 + tests/test/projection.rs | 24 +++++++++++++ 9 files changed, 145 insertions(+), 5 deletions(-) diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index a337ab45ecf..ffb7d30ce3d 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -892,11 +892,18 @@ impl LowerWithEnv for Lifetime { } } -impl LowerWithEnv for (&Impl, ImplId, &AssociatedTyValueIds) { +impl LowerWithEnv + for ( + &Impl, + ImplId, + &AssociatedTyValueIds, + &AssociatedConstValueIds, + ) +{ type Lowered = rust_ir::ImplDatum; fn lower(&self, env: &Env) -> LowerResult { - let (impl_, impl_id, associated_ty_value_ids) = self; + let (impl_, impl_id, associated_ty_value_ids, associated_const_value_ids) = self; let polarity = impl_.polarity.lower(); let binders = env.in_binders(impl_.all_parameters(), |env| { @@ -926,6 +933,12 @@ impl LowerWithEnv for (&Impl, ImplId, &AssociatedTyValueIds) { .map(|atv| associated_ty_value_ids[&(*impl_id, atv.name.str.clone())]) .collect(); + let associated_const_value_ids = impl_ + .assoc_const_values + .iter() + .map(|acv| associated_const_value_ids[&(*impl_id, acv.name.str.clone())]) + .collect(); + debug!(?associated_ty_value_ids); Ok(rust_ir::ImplDatum { @@ -933,6 +946,7 @@ impl LowerWithEnv for (&Impl, ImplId, &AssociatedTyValueIds) { binders, impl_type: impl_.impl_type.lower(), associated_ty_value_ids, + associated_const_value_ids, }) } } diff --git a/chalk-integration/src/lowering/env.rs b/chalk-integration/src/lowering/env.rs index b585d26dfc4..a05ce60a7d3 100644 --- a/chalk-integration/src/lowering/env.rs +++ b/chalk-integration/src/lowering/env.rs @@ -5,7 +5,7 @@ use chalk_ir::{ }; use chalk_ir::{cast::Cast, ForeignDefId, WithKind}; use chalk_parse::ast::*; -use chalk_solve::rust_ir::AssociatedTyValueId; +use chalk_solve::rust_ir::{AssociatedConstValueId, AssociatedTyValueId}; use std::collections::BTreeMap; use crate::error::RustIrError; @@ -28,6 +28,10 @@ pub type GeneratorKinds = BTreeMap, TypeKind>; pub type AssociatedTyLookups = BTreeMap<(chalk_ir::TraitId, Ident), AssociatedTyLookup>; pub type AssociatedTyValueIds = BTreeMap<(chalk_ir::ImplId, Ident), AssociatedTyValueId>; + +pub type AssociatedConstLookups = BTreeMap<(chalk_ir::TraitId, Ident), AssociatedConstLookup>; +pub type AssociatedConstValueIds = + BTreeMap<(chalk_ir::ImplId, Ident), AssociatedConstValueId>; pub type ForeignIds = BTreeMap>; pub type ParameterMap = BTreeMap>; @@ -75,6 +79,21 @@ pub struct AssociatedTyLookup { pub addl_variable_kinds: Vec>, } +/// Information about an associated const **declaration** (i.e., an +/// `AssociatedConstDatum`). This information is gathered in the first +/// phase of creating the Rust IR and is then later used to lookup the +/// "id" of an associated const. +/// +/// ```ignore +/// trait Foo { +/// const Bar: = XXX; // <-- associated const declaration +/// } +/// ``` +#[derive(Debug, PartialEq, Eq)] +pub struct AssociatedConstLookup { + pub id: chalk_ir::AssocItemId, +} + pub enum TypeLookup<'k> { Parameter(&'k WithKind), Adt(AdtId), diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index f579ab44776..6f4b348bf13 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -25,6 +25,10 @@ pub(super) struct ProgramLowerer { associated_ty_lookups: AssociatedTyLookups, associated_ty_value_ids: AssociatedTyValueIds, + + associated_const_lookups: AssociatedConstLookups, + associated_const_value_ids: AssociatedConstValueIds, + adt_ids: AdtIds, fn_def_ids: FnDefIds, closure_ids: ClosureIds, @@ -153,6 +157,7 @@ impl ProgramLowerer { let mut trait_data = BTreeMap::new(); let mut well_known_traits = BTreeMap::new(); let mut impl_data = BTreeMap::new(); + let mut associated_const_values = BTreeMap::new(); let mut associated_ty_data = BTreeMap::new(); let mut associated_ty_values = BTreeMap::new(); let mut opaque_ty_data = BTreeMap::new(); @@ -316,7 +321,13 @@ impl ProgramLowerer { Item::Impl(ref impl_defn) => { let impl_id = ImplId(raw_id); let impl_datum = Arc::new( - (impl_defn, impl_id, &self.associated_ty_value_ids).lower(&empty_env)?, + ( + impl_defn, + impl_id, + &self.associated_ty_value_ids, + &self.associated_const_value_ids, + ) + .lower(&empty_env)?, ); impl_data.insert(impl_id, impl_datum.clone()); let trait_id = impl_datum.trait_id(); @@ -348,6 +359,19 @@ impl ProgramLowerer { }), ); } + + for acv in &impl_defn.assoc_const_values { + let acv_id = self.associated_const_value_ids[&(impl_id, acv.name.str.clone())]; + let lookup = &self.associated_const_lookups[&(trait_id, acv.name.str.clone())]; + + associated_const_values.insert( + acv_id, + Arc::new(rust_ir::AssociatedConstValue { + impl_id, + associated_const_id: lookup.id, + }), + ); + } } Item::Clause(ref clause) => { custom_clauses.extend(clause.lower(&empty_env)?); @@ -495,6 +519,7 @@ impl ProgramLowerer { trait_data, well_known_traits, impl_data, + associated_const_values, associated_ty_values, associated_ty_data, opaque_ty_ids: self.opaque_ty_ids, diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 84de2c75744..5fb3fa1e8a5 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -10,6 +10,7 @@ use chalk_ir::{ }; use chalk_solve::rust_ir::{ AdtDatum, AdtRepr, AdtSizeAlign, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, + AssociatedConstValue, AssociatedConstValueId, ClosureKind, FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, ImplDatum, ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait, }; @@ -78,6 +79,10 @@ pub struct Program { pub associated_ty_values: BTreeMap, Arc>>, + /// For each associated const value `const Foo: = XXX` found in an impl: + pub associated_const_values: + BTreeMap, Arc>>, + // From opaque type name to item-id. Used during lowering only. pub opaque_ty_ids: BTreeMap>, diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index f5ec08d09c7..986abe6a2cb 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -276,6 +276,7 @@ pub struct Impl { pub polarity: Polarity, pub where_clauses: Vec, pub assoc_ty_values: Vec, + pub assoc_const_values: Vec, pub impl_type: ImplType, } @@ -293,6 +294,13 @@ pub struct AssocTyValue { pub default: bool, } +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct AssocConstValue { + pub name: Identifier, + pub ty: Ty, + pub value: Const, +} + #[derive(Clone, PartialEq, Eq, Debug)] pub enum Ty { Id { diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index a148551e8e7..ca7bff427bd 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -354,7 +354,7 @@ QuantifiedInlineBound: QuantifiedInlineBound = { Impl: Impl = { "impl" > > "for" - "{" "}" => + "{" "}" => { let mut args = vec![GenericArg::Ty(s)]; args.extend(a); @@ -367,6 +367,7 @@ Impl: Impl = { }, where_clauses: w, assoc_ty_values: assoc, + assoc_const_values: assoc_const, impl_type: external.map(|_| ImplType::External).unwrap_or(ImplType::Local), } }, @@ -397,6 +398,14 @@ AssocTyValue: AssocTyValue = { }, }; +AssocConstValue: AssocConstValue = { + "const" ":" "=" ";" => AssocConstValue { + name:n, + ty: ty, + value:v, + }, +}; + pub Ty: Ty = { => Ty::Id { name: n }, TyWithoutId, diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index a55604d88e9..15671367aa6 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -18,15 +18,23 @@ use std::ops::ControlFlow; #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct AssociatedTyValueId(pub I::DefId); +/// Identifier for an "associated const value" found in some impl. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct AssociatedConstValueId(pub I::DefId); + chalk_ir::id_visit!(AssociatedTyValueId); chalk_ir::id_fold!(AssociatedTyValueId); +chalk_ir::id_visit!(AssociatedConstValueId); +chalk_ir::id_fold!(AssociatedConstValueId); + #[derive(Clone, Debug, PartialEq, Eq, Hash, Visit)] pub struct ImplDatum { pub polarity: Polarity, pub binders: Binders>, pub impl_type: ImplType, pub associated_ty_value_ids: Vec>, + pub associated_const_value_ids: Vec>, } impl ImplDatum { @@ -619,6 +627,33 @@ pub struct AssociatedTyValue { pub value: Binders>, } +#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)] +pub struct AssociatedConstValue { + /// Impl in which this associated type value is found. You might + /// need to look at this to find the generic parameters defined on + /// the impl, for example. + /// + /// ```ignore + /// impl Iterator for Foo { // <-- refers to this impl + /// const Item: usize = XXX; // <-- (where this is self) + /// } + /// ``` + pub impl_id: ImplId, + + /// Associated type being defined. + /// + /// ```ignore + /// impl Iterator for Foo { + /// const Item: usize = XXX; // <-- (where this is self) + /// } + /// ... + /// trait Iterator { + /// const Item: usize; // <-- refers to this declaration here! + /// } + /// ``` + pub associated_const_id: AssocItemId, +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)] pub struct AssociatedTyValueBound { /// Type that we normalize to. The X in `type Foo<'a> = X`. diff --git a/tests/integration/panic.rs b/tests/integration/panic.rs index c42d61ae76d..9c6a23ca418 100644 --- a/tests/integration/panic.rs +++ b/tests/integration/panic.rs @@ -115,6 +115,7 @@ impl RustIrDatabase for MockDatabase { binders, impl_type: ImplType::Local, associated_ty_value_ids: vec![], + associated_const_value_ids: vec![], }) } diff --git a/tests/test/projection.rs b/tests/test/projection.rs index aaddd17ffa8..9094e0dd363 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -1107,3 +1107,27 @@ fn projection_to_opaque() { } } } + +#[test] +fn const_projection() { + test! { + program { + trait ConstTrait { + const ID: usize; + } + trait OtherTrait {} + impl OtherTrait for U where U: ConstTrait {} + impl ConstTrait for () { + const ID: usize = 3; + } + impl ConstTrait for i32 { + const ID: usize = 5; + } + } + + goal { + } yields { + expect![["Unique"]] + } + } +} From 95861041eeaea602f053aac9d992ac1ac928524b Mon Sep 17 00:00:00 2001 From: kadmin Date: Mon, 2 May 2022 20:43:27 +0000 Subject: [PATCH 04/14] Add const eq where clauses --- chalk-integration/src/lowering.rs | 6 +++ chalk-integration/src/lowering/env.rs | 3 +- .../src/lowering/program_lowerer.rs | 16 ++++--- chalk-integration/src/program.rs | 8 ++-- chalk-ir/src/debug.rs | 7 +++ chalk-ir/src/lib.rs | 46 +++++++++++++++++++ chalk-parse/src/ast.rs | 24 ++++++++-- chalk-parse/src/parser.lalrpop | 8 ++++ tests/test/projection.rs | 2 +- 9 files changed, 103 insertions(+), 17 deletions(-) diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index ffb7d30ce3d..cd8d4c3ad55 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -171,6 +171,12 @@ impl LowerWithEnv for WhereClause { }), chalk_ir::WhereClause::Implemented(projection.trait_ref.lower(env)?), ], + WhereClause::ConstProjectionEq { projection, val } => { + vec![chalk_ir::WhereClause::ConstEq(chalk_ir::ConstEq { + term: chalk_ir::AliasTy::Projection(projection.lower(env)?), + ct: val.lower(env)?, + })] + } WhereClause::LifetimeOutlives { a, b } => { vec![chalk_ir::WhereClause::LifetimeOutlives( chalk_ir::LifetimeOutlives { diff --git a/chalk-integration/src/lowering/env.rs b/chalk-integration/src/lowering/env.rs index a05ce60a7d3..07c21e63145 100644 --- a/chalk-integration/src/lowering/env.rs +++ b/chalk-integration/src/lowering/env.rs @@ -29,7 +29,8 @@ pub type AssociatedTyLookups = BTreeMap<(chalk_ir::TraitId, Ident), Ass pub type AssociatedTyValueIds = BTreeMap<(chalk_ir::ImplId, Ident), AssociatedTyValueId>; -pub type AssociatedConstLookups = BTreeMap<(chalk_ir::TraitId, Ident), AssociatedConstLookup>; +pub type AssociatedConstLookups = + BTreeMap<(chalk_ir::TraitId, Ident), AssociatedConstLookup>; pub type AssociatedConstValueIds = BTreeMap<(chalk_ir::ImplId, Ident), AssociatedConstValueId>; pub type ForeignIds = BTreeMap>; diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index 6f4b348bf13..9b274b8cf81 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -361,15 +361,17 @@ impl ProgramLowerer { } for acv in &impl_defn.assoc_const_values { - let acv_id = self.associated_const_value_ids[&(impl_id, acv.name.str.clone())]; - let lookup = &self.associated_const_lookups[&(trait_id, acv.name.str.clone())]; + let acv_id = + self.associated_const_value_ids[&(impl_id, acv.name.str.clone())]; + let lookup = + &self.associated_const_lookups[&(trait_id, acv.name.str.clone())]; associated_const_values.insert( - acv_id, - Arc::new(rust_ir::AssociatedConstValue { - impl_id, - associated_const_id: lookup.id, - }), + acv_id, + Arc::new(rust_ir::AssociatedConstValue { + impl_id, + associated_const_id: lookup.id, + }), ); } } diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 5fb3fa1e8a5..4b76f0e2401 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -9,10 +9,10 @@ use chalk_ir::{ Substitution, TraitId, Ty, TyKind, UintTy, Variances, }; use chalk_solve::rust_ir::{ - AdtDatum, AdtRepr, AdtSizeAlign, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, - AssociatedConstValue, AssociatedConstValueId, - ClosureKind, FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, - ImplDatum, ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait, + AdtDatum, AdtRepr, AdtSizeAlign, AssociatedConstValue, AssociatedConstValueId, + AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ClosureKind, FnDefDatum, + FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, ImplDatum, ImplType, + OpaqueTyDatum, TraitDatum, WellKnownTrait, }; use chalk_solve::split::Split; use chalk_solve::RustIrDatabase; diff --git a/chalk-ir/src/debug.rs b/chalk-ir/src/debug.rs index 10da316cce3..43d3eb2a783 100644 --- a/chalk-ir/src/debug.rs +++ b/chalk-ir/src/debug.rs @@ -786,11 +786,18 @@ impl Debug for AliasEq { } } +impl Debug for ConstEq { + fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { + write!(fmt, "ConstEq(const {:?} = {:?})", self.term, self.ct) + } +} + impl Debug for WhereClause { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { match self { WhereClause::Implemented(tr) => write!(fmt, "Implemented({:?})", tr.with_colon()), WhereClause::AliasEq(a) => write!(fmt, "{:?}", a), + WhereClause::ConstEq(a) => write!(fmt, "{:?}", a), WhereClause::LifetimeOutlives(l_o) => write!(fmt, "{:?}", l_o), WhereClause::TypeOutlives(t_o) => write!(fmt, "{:?}", t_o), } diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index 4038c0211d0..194656ba9f5 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -728,6 +728,26 @@ impl TyKind { dyn_flags |= alias_eq.alias.compute_flags(interner); dyn_flags |= alias_eq.ty.data(interner).flags; } + WhereClause::ConstEq(ct_eq) => { + // TODO it's not a type projection but is that fine? + // TODO do I need to add other flags here? + dyn_flags |= TypeFlags::HAS_TY_PROJECTION; + let const_data = ct_eq.ct.data(interner); + dyn_flags |= const_data.ty.data(interner).flags + | match const_data.value { + ConstValue::BoundVar(_) | ConstValue::Concrete(_) => { + TypeFlags::empty() + } + ConstValue::InferenceVar(_) => { + TypeFlags::HAS_CT_INFER + | TypeFlags::STILL_FURTHER_SPECIALIZABLE + } + ConstValue::Placeholder(_) => { + TypeFlags::HAS_CT_PLACEHOLDER + | TypeFlags::STILL_FURTHER_SPECIALIZABLE + } + } + } WhereClause::LifetimeOutlives(lifetime_outlives) => { dyn_flags |= lifetime_outlives.a.compute_flags(interner) | lifetime_outlives.b.compute_flags(interner); @@ -1743,6 +1763,8 @@ pub enum WhereClause { LifetimeOutlives(LifetimeOutlives), /// Type outlives a lifetime. TypeOutlives(TypeOutlives), + /// Const is equal to another const + ConstEq(ConstEq), } impl Copy for WhereClause @@ -1750,6 +1772,7 @@ where I::InternedSubstitution: Copy, I::InternedLifetime: Copy, I::InternedType: Copy, + I::InternedConst: Copy, { } @@ -1908,6 +1931,7 @@ where I::InternedSubstitution: Copy, I::InternedLifetime: Copy, I::InternedType: Copy, + I::InternedConst: Copy, { } @@ -1939,6 +1963,7 @@ impl WhereClause { match self { WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id), WhereClause::AliasEq(_) => None, + WhereClause::ConstEq(_) => None, WhereClause::LifetimeOutlives(_) => None, WhereClause::TypeOutlives(_) => None, } @@ -2046,6 +2071,26 @@ impl HasInterner for AliasEq { type Interner = I; } +/// Proves **equality** between an alias and a type. +#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, Zip)] +#[allow(missing_docs)] +pub struct ConstEq { + /// The id for the associated type member. + pub term: AssocItemId, + + pub ct: Const, +} +impl Copy for ConstEq +where + I::InternedSubstitution: Copy, + I::InternedConst: Copy, +{ +} + +impl HasInterner for ConstEq { + type Interner = I; +} + /// Indicates that the `value` is universally quantified over `N` /// parameters of the given kinds, where `N == self.binders.len()`. A /// variable with depth `i < N` refers to the value at @@ -2610,6 +2655,7 @@ pub enum GoalData { impl Copy for GoalData where I::InternedType: Copy, + I::InternedConst: Copy, I::InternedLifetime: Copy, I::InternedGenericArg: Copy, I::InternedSubstitution: Copy, diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index 986abe6a2cb..6120ae3fc66 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -455,10 +455,26 @@ impl fmt::Display for Identifier { #[derive(Clone, PartialEq, Eq, Debug)] pub enum WhereClause { - Implemented { trait_ref: TraitRef }, - ProjectionEq { projection: ProjectionTerm, ty: Ty }, - LifetimeOutlives { a: Lifetime, b: Lifetime }, - TypeOutlives { ty: Ty, lifetime: Lifetime }, + Implemented { + trait_ref: TraitRef, + }, + ProjectionEq { + projection: ProjectionTerm, + ty: Ty, + }, + ConstProjectionEq { + projection: ProjectionTerm, + val: Const, + }, + + LifetimeOutlives { + a: Lifetime, + b: Lifetime, + }, + TypeOutlives { + ty: Ty, + lifetime: Lifetime, + }, } #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index ca7bff427bd..506b5b6cea1 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -588,6 +588,14 @@ InlineClause: Clause = { WhereClause: WhereClause = { > => WhereClause::Implemented { trait_ref: t }, + ":" "<" "const" "=" ">" => { + let args = vec![GenericArg::Ty(s)]; + let trait_ref = TraitRef { trait_name: t, args: args }; + let projection = ProjectionTerm { trait_ref, name, args: vec![] }; + + WhereClause::ConstProjectionEq { projection, val } + }, + // `T: Foo` -- projection equality ":" "<" > ",")?> > "=" ">" => diff --git a/tests/test/projection.rs b/tests/test/projection.rs index 9094e0dd363..26f5e0bfec8 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -1116,7 +1116,7 @@ fn const_projection() { const ID: usize; } trait OtherTrait {} - impl OtherTrait for U where U: ConstTrait {} + impl OtherTrait for U where U: ConstTrait {} impl ConstTrait for () { const ID: usize = 3; } From 78f535a0f2f7b2b6b57c94ec89479b1863601eec Mon Sep 17 00:00:00 2001 From: kadmin Date: Thu, 5 May 2022 04:07:30 +0000 Subject: [PATCH 05/14] Add ConstEq to many match cases Where trivial, add ConstEq, otherwise defer to todos --- chalk-integration/src/db.rs | 8 +++++++ chalk-integration/src/lowering.rs | 3 ++- .../src/lowering/program_lowerer.rs | 5 ++++ chalk-integration/src/program.rs | 8 +++++++ chalk-solve/src/clauses.rs | 4 ++++ chalk-solve/src/clauses/dyn_ty.rs | 2 +- chalk-solve/src/clauses/program_clauses.rs | 2 +- chalk-solve/src/clauses/super_traits.rs | 7 +++--- chalk-solve/src/coinductive_goal.rs | 7 +++--- chalk-solve/src/display.rs | 1 + chalk-solve/src/display/bounds.rs | 7 ++++++ chalk-solve/src/display/stub.rs | 9 ++++++- chalk-solve/src/infer/unify.rs | 3 +++ chalk-solve/src/lib.rs | 3 +++ chalk-solve/src/logging_db.rs | 16 +++++++++++++ chalk-solve/src/logging_db/id_collector.rs | 4 ++++ chalk-solve/src/rust_ir.rs | 24 +++++++++++++++++++ chalk-solve/src/wf.rs | 4 ++++ 18 files changed, 107 insertions(+), 10 deletions(-) diff --git a/chalk-integration/src/db.rs b/chalk-integration/src/db.rs index c62e5c7fb79..fcdae408d34 100644 --- a/chalk-integration/src/db.rs +++ b/chalk-integration/src/db.rs @@ -14,6 +14,7 @@ use chalk_ir::{ }; use chalk_solve::rust_ir::{ AdtDatum, AdtRepr, AdtSizeAlign, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, + AssociatedConstDatum, ClosureKind, FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, ImplDatum, OpaqueTyDatum, TraitDatum, WellKnownTrait, }; @@ -91,6 +92,13 @@ impl RustIrDatabase for ChalkDatabase { self.program_ir().unwrap().associated_ty_data(ty) } + fn associated_const_data( + &self, + ct: AssocItemId, + ) -> Arc> { + self.program_ir().unwrap().associated_const_data(ct) + } + fn trait_datum(&self, id: TraitId) -> Arc> { self.program_ir().unwrap().trait_datum(id) } diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index cd8d4c3ad55..1afe6c8da53 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -173,7 +173,8 @@ impl LowerWithEnv for WhereClause { ], WhereClause::ConstProjectionEq { projection, val } => { vec![chalk_ir::WhereClause::ConstEq(chalk_ir::ConstEq { - term: chalk_ir::AliasTy::Projection(projection.lower(env)?), + // TODO maybe this should just be a projection term instead + term: projection.lower(env)?.associated_term_id, ct: val.lower(env)?, })] } diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index 9b274b8cf81..c28946f7b63 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -158,6 +158,7 @@ impl ProgramLowerer { let mut well_known_traits = BTreeMap::new(); let mut impl_data = BTreeMap::new(); let mut associated_const_values = BTreeMap::new(); + let mut associated_const_data = BTreeMap::new(); let mut associated_ty_data = BTreeMap::new(); let mut associated_ty_values = BTreeMap::new(); let mut opaque_ty_data = BTreeMap::new(); @@ -317,6 +318,9 @@ impl ProgramLowerer { }), ); } + for assoc_ct_defn in &trait_defn.assoc_const_defns { + todo!(); + } } Item::Impl(ref impl_defn) => { let impl_id = ImplId(raw_id); @@ -522,6 +526,7 @@ impl ProgramLowerer { well_known_traits, impl_data, associated_const_values, + associated_const_data, associated_ty_values, associated_ty_data, opaque_ty_ids: self.opaque_ty_ids, diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 4b76f0e2401..d27c76611d3 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -10,6 +10,7 @@ use chalk_ir::{ }; use chalk_solve::rust_ir::{ AdtDatum, AdtRepr, AdtSizeAlign, AssociatedConstValue, AssociatedConstValueId, + AssociatedConstDatum, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ClosureKind, FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, ImplDatum, ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait, @@ -104,6 +105,9 @@ pub struct Program { /// For each associated ty declaration `type Foo` found in a trait: pub associated_ty_data: BTreeMap, Arc>>, + /// For each associated const declaration `const Foo` found in a trait: + pub associated_const_data: BTreeMap, Arc>>, + /// For each user-specified clause pub custom_clauses: Vec>, @@ -395,6 +399,10 @@ impl RustIrDatabase for Program { self.associated_ty_data[&ty].clone() } + fn associated_const_data(&self, ct: AssocItemId) -> Arc> { + self.associated_const_data[&ct].clone() + } + fn trait_datum(&self, id: TraitId) -> Arc> { self.trait_data[&id].clone() } diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index 780f437f053..2b953639bc6 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -570,6 +570,9 @@ pub fn program_clauses_that_could_match( }) }); } + DomainGoal::Holds(WhereClause::ConstEq(const_eq)) => { + todo!() + } DomainGoal::WellFormed(WellFormed::Trait(trait_ref)) | DomainGoal::LocalImplAllowed(trait_ref) => { db.trait_datum(trait_ref.trait_id) @@ -1071,6 +1074,7 @@ fn match_ty( vec![DomainGoal::WellFormed(WellFormed::Trait(trait_ref.clone()))] } WhereClause::AliasEq(_) + | WhereClause::ConstEq(_) | WhereClause::LifetimeOutlives(_) | WhereClause::TypeOutlives(_) => vec![], } diff --git a/chalk-solve/src/clauses/dyn_ty.rs b/chalk-solve/src/clauses/dyn_ty.rs index 505da43f972..efb778c6746 100644 --- a/chalk-solve/src/clauses/dyn_ty.rs +++ b/chalk-solve/src/clauses/dyn_ty.rs @@ -72,7 +72,7 @@ pub(super) fn build_dyn_self_ty_clauses( ) } // FIXME: Associated item bindings are just taken as facts (?) - WhereClause::AliasEq(_) => builder.push_fact(bound), + WhereClause::AliasEq(_) | WhereClause::ConstEq(_) => builder.push_fact(bound), WhereClause::LifetimeOutlives(..) => {} WhereClause::TypeOutlives(..) => {} }); diff --git a/chalk-solve/src/clauses/program_clauses.rs b/chalk-solve/src/clauses/program_clauses.rs index ddba792871d..80faf55ae22 100644 --- a/chalk-solve/src/clauses/program_clauses.rs +++ b/chalk-solve/src/clauses/program_clauses.rs @@ -206,7 +206,7 @@ impl ToProgramClauses for OpaqueTyDatum { ) } // FIXME: Associated item bindings are just taken as facts (?) - WhereClause::AliasEq(_) => builder.push_fact(bound), + WhereClause::AliasEq(_) | WhereClause::ConstEq(_) => builder.push_fact(bound), WhereClause::LifetimeOutlives(..) => {} WhereClause::TypeOutlives(..) => {} }); diff --git a/chalk-solve/src/clauses/super_traits.rs b/chalk-solve/src/clauses/super_traits.rs index 3110b03e8d1..13005d9b8d5 100644 --- a/chalk-solve/src/clauses/super_traits.rs +++ b/chalk-solve/src/clauses/super_traits.rs @@ -93,9 +93,10 @@ pub fn super_traits( } Some(tr.clone()) } - WhereClause::AliasEq(_) => None, - WhereClause::LifetimeOutlives(..) => None, - WhereClause::TypeOutlives(..) => None, + WhereClause::AliasEq(_) + | WhereClause::LifetimeOutlives(..) + | WhereClause::ConstEq(_) + | WhereClause::TypeOutlives(..) => None, }) }) .collect::>() diff --git a/chalk-solve/src/coinductive_goal.rs b/chalk-solve/src/coinductive_goal.rs index cdb5cca108d..9198b28694f 100644 --- a/chalk-solve/src/coinductive_goal.rs +++ b/chalk-solve/src/coinductive_goal.rs @@ -23,9 +23,10 @@ impl IsCoinductive for Goal { db.trait_datum(tr.trait_id).is_auto_trait() || db.trait_datum(tr.trait_id).is_coinductive_trait() } - WhereClause::AliasEq(..) => false, - WhereClause::LifetimeOutlives(..) => false, - WhereClause::TypeOutlives(..) => false, + WhereClause::AliasEq(_) + | WhereClause::LifetimeOutlives(..) + | WhereClause::TypeOutlives(..) + | WhereClause::ConstEq(_) => false, }, GoalData::DomainGoal(DomainGoal::WellFormed(WellFormed::Trait(..))) => true, GoalData::Quantified(QuantifierKind::ForAll, goal) => { diff --git a/chalk-solve/src/display.rs b/chalk-solve/src/display.rs index bb1f7a3c542..4c357bdb209 100644 --- a/chalk-solve/src/display.rs +++ b/chalk-solve/src/display.rs @@ -165,6 +165,7 @@ fn display_self_where_clauses_as_bounds<'a, I: Interner>( } AliasTy::Opaque(opaque) => opaque.display(s).fmt(f), }, + WhereClause::ConstEq(_) => todo!(), WhereClause::LifetimeOutlives(lifetime) => lifetime.display(s).fmt(f), WhereClause::TypeOutlives(ty) => ty.display(s).fmt(f), } diff --git a/chalk-solve/src/display/bounds.rs b/chalk-solve/src/display/bounds.rs index 3c6bfde14f4..33305a81184 100644 --- a/chalk-solve/src/display/bounds.rs +++ b/chalk-solve/src/display/bounds.rs @@ -91,6 +91,7 @@ impl RenderAsRust for WhereClause { match self { WhereClause::Implemented(trait_ref) => trait_ref.fmt(s, f), WhereClause::AliasEq(alias_eq) => alias_eq.fmt(s, f), + WhereClause::ConstEq(const_eq) => const_eq.fmt(s, f), WhereClause::LifetimeOutlives(lifetime) => lifetime.display(s).fmt(f), WhereClause::TypeOutlives(ty) => ty.display(s).fmt(f), } @@ -153,6 +154,12 @@ impl RenderAsRust for AliasEq { } } +impl RenderAsRust for ConstEq { + fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { + todo!() + } +} + impl RenderAsRust for LifetimeOutlives { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { // a': 'b diff --git a/chalk-solve/src/display/stub.rs b/chalk-solve/src/display/stub.rs index 7862a5c3463..64968ab1658 100644 --- a/chalk-solve/src/display/stub.rs +++ b/chalk-solve/src/display/stub.rs @@ -44,7 +44,7 @@ impl> RustIrDatabase for StubWrapper<'_, D fn associated_ty_data( &self, ty: chalk_ir::AssocItemId, - ) -> std::sync::Arc> { + ) -> Arc> { let mut v = (*self.db.associated_ty_data(ty)).clone(); v.binders = Binders::new( v.binders.binders.clone(), @@ -56,6 +56,13 @@ impl> RustIrDatabase for StubWrapper<'_, D Arc::new(v) } + fn associated_const_data( + &self, + ct: chalk_ir::AssocItemId, + ) -> Arc> { + Arc::new((*self.db.associated_const_data(ct)).clone()) + } + fn trait_datum( &self, trait_id: chalk_ir::TraitId, diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index 9c1782ea5ce..4845d03ad07 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -672,6 +672,9 @@ impl<'t, I: Interner> Unifier<'t, I> { self.table.new_variable(universe_index).to_ty(interner); WhereClause::AliasEq(AliasEq { alias, ty }) } + WhereClause::ConstEq(ConstEq { term, ct }) => { + todo!(); + } WhereClause::TypeOutlives(_) => { let lifetime_var = self.table.new_variable(universe_index); let lifetime = lifetime_var.to_lifetime(interner); diff --git a/chalk-solve/src/lib.rs b/chalk-solve/src/lib.rs index d49c9960bfb..2bd7c9aeb42 100644 --- a/chalk-solve/src/lib.rs +++ b/chalk-solve/src/lib.rs @@ -49,6 +49,9 @@ pub trait RustIrDatabase: Debug { /// Returns the datum for the associated type with the given id. fn associated_ty_data(&self, ty: AssocItemId) -> Arc>; + /// Returns the datum for the associated type with the given id. + fn associated_const_data(&self, ty: AssocItemId) -> Arc>; + /// Returns the datum for the definition with the given id. fn trait_datum(&self, trait_id: TraitId) -> Arc>; diff --git a/chalk-solve/src/logging_db.rs b/chalk-solve/src/logging_db.rs index bc9d2377ff0..b50b279a987 100644 --- a/chalk-solve/src/logging_db.rs +++ b/chalk-solve/src/logging_db.rs @@ -128,6 +128,15 @@ where ty_datum } + fn associated_const_data( + &self, + ct: chalk_ir::AssocItemId, + ) -> Arc> { + let ct_datum = self.ws.db().associated_const_data(ct); + self.record(ct_datum.trait_id); + ct_datum + } + fn trait_datum(&self, trait_id: TraitId) -> Arc> { self.record(trait_id); self.ws.db().trait_datum(trait_id) @@ -402,6 +411,13 @@ where self.db.associated_ty_data(ty) } + fn associated_const_data( + &self, + ct: chalk_ir::AssocItemId, + ) -> Arc> { + self.db.associated_const_data(ct) + } + fn trait_datum(&self, trait_id: TraitId) -> Arc> { self.db.trait_datum(trait_id) } diff --git a/chalk-solve/src/logging_db/id_collector.rs b/chalk-solve/src/logging_db/id_collector.rs index 5a0412f4d64..947ef3e145f 100644 --- a/chalk-solve/src/logging_db/id_collector.rs +++ b/chalk-solve/src/logging_db/id_collector.rs @@ -154,6 +154,10 @@ impl<'i, I: Interner, DB: RustIrDatabase> Visitor for IdCollector<'i, I, D match where_clause { WhereClause::Implemented(trait_ref) => self.record(trait_ref.trait_id), WhereClause::AliasEq(alias_eq) => self.visit_alias(&alias_eq.alias), + WhereClause::ConstEq(const_eq) => { + self.db.associated_const_data(const_eq.term); + self.visit_const(&const_eq.ct, outer_binder)?; + } WhereClause::LifetimeOutlives(_lifetime_outlives) => (), WhereClause::TypeOutlives(_type_outlives) => (), } diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index 15671367aa6..2dab2810ea6 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -524,6 +524,30 @@ impl Visit for AssociatedTyDatum { } } +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct AssociatedConstDatum { + /// The trait this associated type is defined in. + pub trait_id: TraitId, + + /// The ID of this associated type + pub id: AssocItemId, + + /// Name of this associated type. + pub name: I::Identifier, +} + +// Manual implementation to avoid I::Identifier type. +impl Visit for AssociatedConstDatum { + fn visit_with( + &self, + visitor: &mut dyn chalk_ir::visit::Visitor, + outer_binder: DebruijnIndex, + ) -> ControlFlow { + try_break!(self.trait_id.visit_with(visitor, outer_binder)); + self.id.visit_with(visitor, outer_binder) + } +} + /// Encodes the parts of `AssociatedTyDatum` where the parameters /// `P0..Pm` are in scope (`bounds` and `where_clauses`). #[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)] diff --git a/chalk-solve/src/wf.rs b/chalk-solve/src/wf.rs index 58703753b4a..a169bfe14ef 100644 --- a/chalk-solve/src/wf.rs +++ b/chalk-solve/src/wf.rs @@ -90,6 +90,10 @@ impl Visitor for InputTypeCollector { .clone() .intern(self.interner) .visit_with(self, outer_binder), + WhereClause::ConstEq(const_eq) => { + const_eq.term.visit_with(self, outer_binder)?; + const_eq.ct.visit_with(self, outer_binder) + } WhereClause::Implemented(trait_ref) => trait_ref.visit_with(self, outer_binder), WhereClause::TypeOutlives(TypeOutlives { ty, .. }) => ty.visit_with(self, outer_binder), WhereClause::LifetimeOutlives(..) => ControlFlow::Continue(()), From 073f7b8d10eb2477d80358823aa2c8b75717e9b2 Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 3 Jun 2022 21:42:36 +0000 Subject: [PATCH 06/14] Continue adding associated term --- chalk-integration/src/db.rs | 26 ++--- chalk-integration/src/lowering.rs | 69 +++++++------- chalk-integration/src/lowering/env.rs | 36 ++----- .../src/lowering/program_lowerer.rs | 80 ++++++---------- chalk-integration/src/program.rs | 47 ++++----- chalk-integration/src/query.rs | 8 +- chalk-ir/src/debug.rs | 11 +-- chalk-ir/src/lib.rs | 79 ++++++--------- chalk-parse/src/ast.rs | 64 +++++++++---- chalk-parse/src/parser.lalrpop | 7 +- chalk-solve/src/clauses.rs | 42 ++++---- chalk-solve/src/clauses/builder.rs | 22 +++++ .../builtin_traits/discriminant_kind.rs | 3 +- .../src/clauses/builtin_traits/fn_family.rs | 3 +- .../src/clauses/builtin_traits/generator.rs | 6 +- chalk-solve/src/clauses/dyn_ty.rs | 2 +- chalk-solve/src/clauses/env_elaborator.rs | 4 +- chalk-solve/src/clauses/program_clauses.rs | 17 ++-- chalk-solve/src/clauses/super_traits.rs | 1 - chalk-solve/src/coinductive_goal.rs | 3 +- chalk-solve/src/display.rs | 3 +- chalk-solve/src/display/bounds.rs | 9 +- chalk-solve/src/display/items.rs | 25 ++--- chalk-solve/src/display/stub.rs | 23 ++--- chalk-solve/src/display/ty.rs | 4 +- chalk-solve/src/infer/unify.rs | 3 - chalk-solve/src/lib.rs | 9 +- chalk-solve/src/logging_db.rs | 44 +++------ chalk-solve/src/logging_db/id_collector.rs | 12 +-- chalk-solve/src/rust_ir.rs | 95 ++++--------------- chalk-solve/src/split.rs | 12 +-- chalk-solve/src/wf.rs | 27 +++--- 32 files changed, 328 insertions(+), 468 deletions(-) diff --git a/chalk-integration/src/db.rs b/chalk-integration/src/db.rs index fcdae408d34..9d5b5a0d38d 100644 --- a/chalk-integration/src/db.rs +++ b/chalk-integration/src/db.rs @@ -13,10 +13,9 @@ use chalk_ir::{ UnificationDatabase, Variances, }; use chalk_solve::rust_ir::{ - AdtDatum, AdtRepr, AdtSizeAlign, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, - AssociatedConstDatum, - ClosureKind, FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, - ImplDatum, OpaqueTyDatum, TraitDatum, WellKnownTrait, + AdtDatum, AdtRepr, AdtSizeAlign, AssociatedTermDatum, AssociatedTermValue, + AssociatedTermValueId, ClosureKind, FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, + GeneratorWitnessDatum, ImplDatum, OpaqueTyDatum, TraitDatum, WellKnownTrait, }; use chalk_solve::{RustIrDatabase, Solution, SubstitutionResult}; use salsa::Database; @@ -88,15 +87,8 @@ impl RustIrDatabase for ChalkDatabase { self.program_ir().unwrap().custom_clauses() } - fn associated_ty_data(&self, ty: AssocItemId) -> Arc> { - self.program_ir().unwrap().associated_ty_data(ty) - } - - fn associated_const_data( - &self, - ct: AssocItemId, - ) -> Arc> { - self.program_ir().unwrap().associated_const_data(ct) + fn associated_term_data(&self, ty: AssocItemId) -> Arc> { + self.program_ir().unwrap().associated_term_data(ty) } fn trait_datum(&self, id: TraitId) -> Arc> { @@ -107,11 +99,11 @@ impl RustIrDatabase for ChalkDatabase { self.program_ir().unwrap().impl_datum(id) } - fn associated_ty_value( + fn associated_term_value( &self, - id: AssociatedTyValueId, - ) -> Arc> { - self.program_ir().unwrap().associated_ty_values[&id].clone() + id: AssociatedTermValueId, + ) -> Arc> { + self.program_ir().unwrap().associated_term_values[&id].clone() } fn opaque_ty_data(&self, id: OpaqueTyId) -> Arc> { diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index 1afe6c8da53..f768a09ebef 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -164,20 +164,13 @@ impl LowerWithEnv for WhereClause { WhereClause::Implemented { trait_ref } => { vec![chalk_ir::WhereClause::Implemented(trait_ref.lower(env)?)] } - WhereClause::ProjectionEq { projection, ty } => vec![ + WhereClause::ProjectionEq { projection, term } => vec![ chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias: chalk_ir::AliasTy::Projection(projection.lower(env)?), - ty: ty.lower(env)?, + term: term.lower(env)?, }), chalk_ir::WhereClause::Implemented(projection.trait_ref.lower(env)?), ], - WhereClause::ConstProjectionEq { projection, val } => { - vec![chalk_ir::WhereClause::ConstEq(chalk_ir::ConstEq { - // TODO maybe this should just be a projection term instead - term: projection.lower(env)?.associated_term_id, - ct: val.lower(env)?, - })] - } WhereClause::LifetimeOutlives { a, b } => { vec![chalk_ir::WhereClause::LifetimeOutlives( chalk_ir::LifetimeOutlives { @@ -223,10 +216,10 @@ impl LowerWithEnv for DomainGoal { .into_iter() .casted(interner) .collect(), - DomainGoal::Normalize { projection, ty } => { + DomainGoal::Normalize { projection, term } => { vec![chalk_ir::DomainGoal::Normalize(chalk_ir::Normalize { alias: chalk_ir::AliasTy::Projection(projection.lower(env)?), - ty: ty.lower(env)?, + term: term.lower(env)?, })] } DomainGoal::TyWellFormed { ty } => vec![chalk_ir::DomainGoal::WellFormed( @@ -853,6 +846,17 @@ impl LowerWithEnv for Const { } } +impl LowerWithEnv for Term { + type Lowered = chalk_ir::Term; + + fn lower(&self, env: &Env) -> LowerResult { + Ok(match self { + Term::Ty(t) => chalk_ir::Term::Ty(t.lower(env)?), + Term::Const(c) => chalk_ir::Term::Const(c.lower(env)?), + }) + } +} + impl LowerWithEnv for GenericArg { type Lowered = chalk_ir::GenericArg; @@ -899,18 +903,11 @@ impl LowerWithEnv for Lifetime { } } -impl LowerWithEnv - for ( - &Impl, - ImplId, - &AssociatedTyValueIds, - &AssociatedConstValueIds, - ) -{ +impl LowerWithEnv for (&Impl, ImplId, &AssociatedTermValueIds) { type Lowered = rust_ir::ImplDatum; fn lower(&self, env: &Env) -> LowerResult { - let (impl_, impl_id, associated_ty_value_ids, associated_const_value_ids) = self; + let (impl_, impl_id, associated_term_value_ids) = self; let polarity = impl_.polarity.lower(); let binders = env.in_binders(impl_.all_parameters(), |env| { @@ -934,26 +931,24 @@ impl LowerWithEnv // lookup the ids for each of the "associated type values" // within the impl, which should have already assigned and // stored in the map - let associated_ty_value_ids = impl_ - .assoc_ty_values - .iter() - .map(|atv| associated_ty_value_ids[&(*impl_id, atv.name.str.clone())]) - .collect(); - - let associated_const_value_ids = impl_ + let assoc_const_values = impl_ .assoc_const_values .iter() - .map(|acv| associated_const_value_ids[&(*impl_id, acv.name.str.clone())]) + .map(|av| associated_term_value_ids[&(*impl_id, av.name.str.clone())]); + let associated_term_value_ids = impl_ + .assoc_ty_values + .iter() + .map(|av| associated_term_value_ids[&(*impl_id, av.name.str.clone())]) + .chain(assoc_const_values) .collect(); - debug!(?associated_ty_value_ids); + debug!(?associated_term_value_ids); Ok(rust_ir::ImplDatum { polarity, binders, impl_type: impl_.impl_type.lower(), - associated_ty_value_ids, - associated_const_value_ids, + associated_term_value_ids, }) } } @@ -1043,17 +1038,17 @@ impl LowerWithEnv for (&TraitDefn, chalk_ir::TraitId) { pub fn lower_goal(goal: &Goal, program: &LoweredProgram) -> LowerResult> { let interner = ChalkIr; - let associated_ty_lookups: BTreeMap<_, _> = program - .associated_ty_data + let associated_term_lookups: BTreeMap<_, _> = program + .associated_term_data .iter() - .map(|(&associated_ty_id, datum)| { + .map(|(&associated_term_id, datum)| { let trait_datum = &program.trait_data[&datum.trait_id]; let num_trait_params = trait_datum.binders.len(interner); let num_addl_params = datum.binders.len(interner) - num_trait_params; let addl_variable_kinds = datum.binders.binders.as_slice(interner)[..num_addl_params].to_owned(); - let lookup = AssociatedTyLookup { - id: associated_ty_id, + let lookup = AssociatedTermLookup { + id: associated_term_id, addl_variable_kinds, }; ((datum.trait_id, datum.name.clone()), lookup) @@ -1079,7 +1074,7 @@ pub fn lower_goal(goal: &Goal, program: &LoweredProgram) -> LowerResult, TypeKind>; pub type AutoTraits = BTreeMap, bool>; pub type OpaqueTyVariableKinds = BTreeMap, TypeKind>; pub type GeneratorKinds = BTreeMap, TypeKind>; -pub type AssociatedTyLookups = BTreeMap<(chalk_ir::TraitId, Ident), AssociatedTyLookup>; -pub type AssociatedTyValueIds = - BTreeMap<(chalk_ir::ImplId, Ident), AssociatedTyValueId>; -pub type AssociatedConstLookups = - BTreeMap<(chalk_ir::TraitId, Ident), AssociatedConstLookup>; -pub type AssociatedConstValueIds = - BTreeMap<(chalk_ir::ImplId, Ident), AssociatedConstValueId>; +pub type AssociatedTermLookups = + BTreeMap<(chalk_ir::TraitId, Ident), AssociatedTermLookup>; +pub type AssociatedTermValueIds = + BTreeMap<(chalk_ir::ImplId, Ident), AssociatedTermValueId>; pub type ForeignIds = BTreeMap>; pub type ParameterMap = BTreeMap>; @@ -51,7 +48,7 @@ pub struct Env<'k> { pub trait_kinds: &'k TraitKinds, pub opaque_ty_ids: &'k OpaqueTyIds, pub opaque_ty_kinds: &'k OpaqueTyVariableKinds, - pub associated_ty_lookups: &'k AssociatedTyLookups, + pub associated_term_lookups: &'k AssociatedTermLookups, pub auto_traits: &'k AutoTraits, pub foreign_ty_ids: &'k ForeignIds, pub generator_ids: &'k GeneratorIds, @@ -75,26 +72,11 @@ pub struct Env<'k> { /// } /// ``` #[derive(Debug, PartialEq, Eq)] -pub struct AssociatedTyLookup { +pub struct AssociatedTermLookup { pub id: chalk_ir::AssocItemId, pub addl_variable_kinds: Vec>, } -/// Information about an associated const **declaration** (i.e., an -/// `AssociatedConstDatum`). This information is gathered in the first -/// phase of creating the Rust IR and is then later used to lookup the -/// "id" of an associated const. -/// -/// ```ignore -/// trait Foo { -/// const Bar: = XXX; // <-- associated const declaration -/// } -/// ``` -#[derive(Debug, PartialEq, Eq)] -pub struct AssociatedConstLookup { - pub id: chalk_ir::AssocItemId, -} - pub enum TypeLookup<'k> { Parameter(&'k WithKind), Adt(AdtId), @@ -236,8 +218,8 @@ impl Env<'_> { &self, trait_id: TraitId, ident: &Identifier, - ) -> LowerResult<&AssociatedTyLookup> { - self.associated_ty_lookups + ) -> LowerResult<&AssociatedTermLookup> { + self.associated_term_lookups .get(&(trait_id, ident.str.clone())) .ok_or_else(|| RustIrError::MissingAssociatedType(ident.clone())) } diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index c28946f7b63..1a8bedd62c5 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -5,7 +5,7 @@ use chalk_ir::{ }; use chalk_parse::ast::*; use chalk_solve::rust_ir::{ - self, Anonymize, AssociatedTyValueId, GeneratorDatum, GeneratorInputOutputDatum, + self, Anonymize, GeneratorDatum, GeneratorInputOutputDatum, GeneratorWitnessDatum, GeneratorWitnessExistential, OpaqueTyDatum, OpaqueTyDatumBound, }; use rust_ir::IntoWhereClauses; @@ -23,11 +23,8 @@ use crate::{interner::ChalkIr, TypeKind, TypeSort}; pub(super) struct ProgramLowerer { next_item_index: u32, - associated_ty_lookups: AssociatedTyLookups, - associated_ty_value_ids: AssociatedTyValueIds, - - associated_const_lookups: AssociatedConstLookups, - associated_const_value_ids: AssociatedConstValueIds, + associated_term_lookups: AssociatedTermLookups, + associated_term_value_ids: AssociatedTermValueIds, adt_ids: AdtIds, fn_def_ids: FnDefIds, @@ -67,19 +64,19 @@ impl ProgramLowerer { } for defn in &d.assoc_ty_defns { let addl_variable_kinds = defn.all_parameters(); - let lookup = AssociatedTyLookup { + let lookup = AssociatedTermLookup { id: AssocItemId(self.next_item_id()), addl_variable_kinds: addl_variable_kinds.anonymize(), }; - self.associated_ty_lookups + self.associated_term_lookups .insert((TraitId(raw_id), defn.name.str.clone()), lookup); } } Item::Impl(d) => { for atv in &d.assoc_ty_values { - let atv_id = AssociatedTyValueId(self.next_item_id()); - self.associated_ty_value_ids + let atv_id = rust_ir::AssociatedTermValueId(self.next_item_id()); + self.associated_term_value_ids .insert((ImplId(raw_id), atv.name.str.clone()), atv_id); } } @@ -157,10 +154,8 @@ impl ProgramLowerer { let mut trait_data = BTreeMap::new(); let mut well_known_traits = BTreeMap::new(); let mut impl_data = BTreeMap::new(); - let mut associated_const_values = BTreeMap::new(); - let mut associated_const_data = BTreeMap::new(); - let mut associated_ty_data = BTreeMap::new(); - let mut associated_ty_values = BTreeMap::new(); + let mut associated_term_data = BTreeMap::new(); + let mut associated_term_values = BTreeMap::new(); let mut opaque_ty_data = BTreeMap::new(); let mut generator_data = BTreeMap::new(); let mut generator_witness_data = BTreeMap::new(); @@ -181,7 +176,7 @@ impl ProgramLowerer { opaque_ty_kinds: &self.opaque_ty_kinds, generator_ids: &self.generator_ids, generator_kinds: &self.generator_kinds, - associated_ty_lookups: &self.associated_ty_lookups, + associated_term_lookups: &self.associated_term_lookups, parameter_map: BTreeMap::new(), auto_traits: &self.auto_traits, foreign_ty_ids: &self.foreign_ty_ids, @@ -275,7 +270,7 @@ impl ProgramLowerer { trait_data.insert(trait_id, Arc::new(trait_datum)); for assoc_ty_defn in &trait_defn.assoc_ty_defns { - let lookup = &self.associated_ty_lookups + let lookup = &self.associated_term_lookups [&(trait_id, assoc_ty_defn.name.str.clone())]; // The parameters in scope for the associated @@ -302,15 +297,15 @@ impl ProgramLowerer { variable_kinds.extend(trait_defn.all_parameters()); let binders = empty_env.in_binders(variable_kinds, |env| { - Ok(rust_ir::AssociatedTyDatumBound { + Ok(rust_ir::AssociatedTermDatumBound { bounds: assoc_ty_defn.bounds.lower(env)?, where_clauses: assoc_ty_defn.where_clauses.lower(env)?, }) })?; - associated_ty_data.insert( + associated_term_data.insert( lookup.id, - Arc::new(rust_ir::AssociatedTyDatum { + Arc::new(rust_ir::AssociatedTermDatum { trait_id: TraitId(raw_id), id: lookup.id, name: assoc_ty_defn.name.str.clone(), @@ -325,20 +320,16 @@ impl ProgramLowerer { Item::Impl(ref impl_defn) => { let impl_id = ImplId(raw_id); let impl_datum = Arc::new( - ( - impl_defn, - impl_id, - &self.associated_ty_value_ids, - &self.associated_const_value_ids, - ) - .lower(&empty_env)?, + (impl_defn, impl_id, &self.associated_term_value_ids).lower(&empty_env)?, ); impl_data.insert(impl_id, impl_datum.clone()); let trait_id = impl_datum.trait_id(); for atv in &impl_defn.assoc_ty_values { - let atv_id = self.associated_ty_value_ids[&(impl_id, atv.name.str.clone())]; - let lookup = &self.associated_ty_lookups[&(trait_id, atv.name.str.clone())]; + let atv_id = + self.associated_term_value_ids[&(impl_id, atv.name.str.clone())]; + let lookup = + &self.associated_term_lookups[&(trait_id, atv.name.str.clone())]; // The parameters in scope for the associated // type definitions are *both* those from the @@ -349,35 +340,20 @@ impl ProgramLowerer { variable_kinds.extend(impl_defn.all_parameters()); let value = empty_env.in_binders(variable_kinds, |env| { - Ok(rust_ir::AssociatedTyValueBound { - ty: atv.value.lower(env)?, - }) + Ok(rust_ir::AssociatedTermValueBound::Ty( + atv.value.lower(env)?, + )) })?; - associated_ty_values.insert( + associated_term_values.insert( atv_id, - Arc::new(rust_ir::AssociatedTyValue { + Arc::new(rust_ir::AssociatedTermValue { impl_id, - associated_ty_id: lookup.id, + associated_term_id: lookup.id, value, }), ); } - - for acv in &impl_defn.assoc_const_values { - let acv_id = - self.associated_const_value_ids[&(impl_id, acv.name.str.clone())]; - let lookup = - &self.associated_const_lookups[&(trait_id, acv.name.str.clone())]; - - associated_const_values.insert( - acv_id, - Arc::new(rust_ir::AssociatedConstValue { - impl_id, - associated_const_id: lookup.id, - }), - ); - } } Item::Clause(ref clause) => { custom_clauses.extend(clause.lower(&empty_env)?); @@ -525,10 +501,8 @@ impl ProgramLowerer { trait_data, well_known_traits, impl_data, - associated_const_values, - associated_const_data, - associated_ty_values, - associated_ty_data, + associated_term_values, + associated_term_data, opaque_ty_ids: self.opaque_ty_ids, opaque_ty_kinds: self.opaque_ty_kinds, opaque_ty_data, diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index d27c76611d3..9765dd73ada 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -9,11 +9,10 @@ use chalk_ir::{ Substitution, TraitId, Ty, TyKind, UintTy, Variances, }; use chalk_solve::rust_ir::{ - AdtDatum, AdtRepr, AdtSizeAlign, AssociatedConstValue, AssociatedConstValueId, - AssociatedConstDatum, - AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ClosureKind, FnDefDatum, - FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, ImplDatum, ImplType, - OpaqueTyDatum, TraitDatum, WellKnownTrait, + AdtDatum, AdtRepr, AdtSizeAlign, + AssociatedTermDatum, AssociatedTermValue, AssociatedTermValueId, ClosureKind, + FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, ImplDatum, + ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait, }; use chalk_solve::split::Split; use chalk_solve::RustIrDatabase; @@ -77,12 +76,11 @@ pub struct Program { pub impl_data: BTreeMap, Arc>>, /// For each associated ty value `type Foo = XXX` found in an impl: - pub associated_ty_values: - BTreeMap, Arc>>, + pub associated_term_values: + BTreeMap, Arc>>, - /// For each associated const value `const Foo: = XXX` found in an impl: - pub associated_const_values: - BTreeMap, Arc>>, + /// For each associated ty declaration `type Foo` found in a trait: + pub associated_term_data: BTreeMap, Arc>>, // From opaque type name to item-id. Used during lowering only. pub opaque_ty_ids: BTreeMap>, @@ -102,12 +100,6 @@ pub struct Program { /// For each trait lang item pub well_known_traits: BTreeMap>, - /// For each associated ty declaration `type Foo` found in a trait: - pub associated_ty_data: BTreeMap, Arc>>, - - /// For each associated const declaration `const Foo` found in a trait: - pub associated_const_data: BTreeMap, Arc>>, - /// For each user-specified clause pub custom_clauses: Vec>, @@ -163,7 +155,7 @@ impl tls::DebugContext for Program { assoc_type_id: AssocItemId, fmt: &mut fmt::Formatter<'_>, ) -> Result<(), fmt::Error> { - if let Some(d) = self.associated_ty_data.get(&assoc_type_id) { + if let Some(d) = self.associated_term_data.get(&assoc_type_id) { write!(fmt, "({:?}::{})", d.trait_id, d.name) } else { fmt.debug_struct("InvalidAssocItemId") @@ -395,12 +387,11 @@ impl RustIrDatabase for Program { self.custom_clauses.clone() } - fn associated_ty_data(&self, ty: AssocItemId) -> Arc> { - self.associated_ty_data[&ty].clone() - } - - fn associated_const_data(&self, ct: AssocItemId) -> Arc> { - self.associated_const_data[&ct].clone() + fn associated_term_data( + &self, + term: AssocItemId, + ) -> Arc> { + self.associated_term_data[&term].clone() } fn trait_datum(&self, id: TraitId) -> Arc> { @@ -411,11 +402,11 @@ impl RustIrDatabase for Program { self.impl_data[&id].clone() } - fn associated_ty_value( + fn associated_term_value( &self, - id: AssociatedTyValueId, - ) -> Arc> { - self.associated_ty_values[&id].clone() + id: AssociatedTermValueId, + ) -> Arc> { + self.associated_term_values[&id].clone() } fn opaque_ty_data(&self, id: OpaqueTyId) -> Arc> { @@ -601,7 +592,7 @@ impl RustIrDatabase for Program { // writer to fail. This is because they use the `Eq` implementation on // Program, which checks for name equality. fn assoc_type_name(&self, assoc_type_id: AssocItemId) -> String { - self.associated_ty_data + self.associated_term_data .get(&assoc_type_id) .unwrap() .name diff --git a/chalk-integration/src/query.rs b/chalk-integration/src/query.rs index 1d074b953d9..f1d213e2949 100644 --- a/chalk-integration/src/query.rs +++ b/chalk-integration/src/query.rs @@ -205,7 +205,7 @@ fn environment(db: &dyn LoweringDatabase) -> Result, Cha let env = chalk_ir::Environment::new(builder.interner()); program - .associated_ty_data + .associated_term_data .values() .for_each(|d| d.to_program_clauses(builder, &env)); @@ -238,10 +238,10 @@ fn environment(db: &dyn LoweringDatabase) -> Result, Cha if datum.is_positive() { datum.to_program_clauses(builder, &env); datum - .associated_ty_value_ids + .associated_term_value_ids .iter() - .map(|&atv_id| db.associated_ty_value(atv_id)) - .for_each(|atv| atv.to_program_clauses(builder, &env)); + .map(|&av_id| db.associated_term_value(av_id)) + .for_each(|av| av.to_program_clauses(builder, &env)); } } diff --git a/chalk-ir/src/debug.rs b/chalk-ir/src/debug.rs index 43d3eb2a783..346ad683704 100644 --- a/chalk-ir/src/debug.rs +++ b/chalk-ir/src/debug.rs @@ -776,19 +776,13 @@ impl<'a, T: Debug> Debug for Angle<'a, T> { impl Debug for Normalize { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { - write!(fmt, "Normalize({:?} -> {:?})", self.alias, self.ty) + write!(fmt, "Normalize({:?} -> {:?})", self.alias, self.term) } } impl Debug for AliasEq { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { - write!(fmt, "AliasEq({:?} = {:?})", self.alias, self.ty) - } -} - -impl Debug for ConstEq { - fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { - write!(fmt, "ConstEq(const {:?} = {:?})", self.term, self.ct) + write!(fmt, "AliasEq({:?} = {:?})", self.alias, self.term) } } @@ -797,7 +791,6 @@ impl Debug for WhereClause { match self { WhereClause::Implemented(tr) => write!(fmt, "Implemented({:?})", tr.with_colon()), WhereClause::AliasEq(a) => write!(fmt, "{:?}", a), - WhereClause::ConstEq(a) => write!(fmt, "{:?}", a), WhereClause::LifetimeOutlives(l_o) => write!(fmt, "{:?}", l_o), WhereClause::TypeOutlives(t_o) => write!(fmt, "{:?}", t_o), } diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index 194656ba9f5..f121d48fea2 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -412,6 +412,22 @@ pub struct Ty { interned: I::InternedType, } +/// A Rust term (const or type). Used for associated items. +#[derive(Debug, Clone, PartialEq, Eq, Hash, HasInterner, Fold, Visit, Zip)] +pub enum Term { + /// On a trait, associated type. + Ty(Ty), + /// On a trait, associated const. + Const(Const), +} + +impl Copy for Term +where + I::InternedType: Copy, + I::InternedConst: Copy, +{ +} + impl Ty { /// Creates a type from `TyKind`. pub fn new(interner: I, data: impl CastTo>) -> Self { @@ -726,27 +742,13 @@ impl TyKind { } WhereClause::AliasEq(alias_eq) => { dyn_flags |= alias_eq.alias.compute_flags(interner); - dyn_flags |= alias_eq.ty.data(interner).flags; - } - WhereClause::ConstEq(ct_eq) => { - // TODO it's not a type projection but is that fine? - // TODO do I need to add other flags here? - dyn_flags |= TypeFlags::HAS_TY_PROJECTION; - let const_data = ct_eq.ct.data(interner); - dyn_flags |= const_data.ty.data(interner).flags - | match const_data.value { - ConstValue::BoundVar(_) | ConstValue::Concrete(_) => { - TypeFlags::empty() - } - ConstValue::InferenceVar(_) => { - TypeFlags::HAS_CT_INFER - | TypeFlags::STILL_FURTHER_SPECIALIZABLE - } - ConstValue::Placeholder(_) => { - TypeFlags::HAS_CT_PLACEHOLDER - | TypeFlags::STILL_FURTHER_SPECIALIZABLE - } - } + dyn_flags |= match &alias_eq.term { + Term::Ty(ty) => ty.data(interner).flags, + Term::Const(ct) => { + let const_data = ct.data(interner); + const_data.ty.data(interner).flags + }, + }; } WhereClause::LifetimeOutlives(lifetime_outlives) => { dyn_flags |= lifetime_outlives.a.compute_flags(interner) @@ -1757,14 +1759,12 @@ where pub enum WhereClause { /// Type implements a trait. Implemented(TraitRef), - /// Type is equal to an alias. + /// Term is equal to an alias. AliasEq(AliasEq), /// One lifetime outlives another. LifetimeOutlives(LifetimeOutlives), /// Type outlives a lifetime. TypeOutlives(TypeOutlives), - /// Const is equal to another const - ConstEq(ConstEq), } impl Copy for WhereClause @@ -1865,7 +1865,7 @@ pub enum DomainGoal { /// True if the trait ref can be derived from in-scope where clauses. FromEnv(FromEnv), - /// True if the alias type can be normalized to some other type + /// True if the alias term can be normalized to some other term Normalize(Normalize), /// True if a type is considered to have been "defined" by the current crate. This is true for @@ -1963,7 +1963,6 @@ impl WhereClause { match self { WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id), WhereClause::AliasEq(_) => None, - WhereClause::ConstEq(_) => None, WhereClause::LifetimeOutlives(_) => None, WhereClause::TypeOutlives(_) => None, } @@ -2042,52 +2041,34 @@ impl Copy for SubtypeGoal where I::InternedType: Copy {} #[allow(missing_docs)] pub struct Normalize { pub alias: AliasTy, - pub ty: Ty, + pub term: Term, } impl Copy for Normalize where I::InternedSubstitution: Copy, I::InternedType: Copy, + I::InternedConst: Copy, { } -/// Proves **equality** between an alias and a type. +/// Proves **equality** between an alias and a term. #[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, Zip)] #[allow(missing_docs)] pub struct AliasEq { pub alias: AliasTy, - pub ty: Ty, + pub term: Term, } impl Copy for AliasEq where I::InternedSubstitution: Copy, I::InternedType: Copy, -{ -} - -impl HasInterner for AliasEq { - type Interner = I; -} - -/// Proves **equality** between an alias and a type. -#[derive(Clone, PartialEq, Eq, Hash, Fold, Visit, Zip)] -#[allow(missing_docs)] -pub struct ConstEq { - /// The id for the associated type member. - pub term: AssocItemId, - - pub ct: Const, -} -impl Copy for ConstEq -where - I::InternedSubstitution: Copy, I::InternedConst: Copy, { } -impl HasInterner for ConstEq { +impl HasInterner for AliasEq { type Interner = I; } diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index 6120ae3fc66..60199d1c96d 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -409,6 +409,12 @@ pub enum Lifetime { Empty, } +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum Term { + Ty(Ty), + Const(Const), +} + #[derive(Clone, PartialEq, Eq, Debug)] pub struct ProjectionTerm { pub trait_ref: TraitRef, @@ -460,13 +466,8 @@ pub enum WhereClause { }, ProjectionEq { projection: ProjectionTerm, - ty: Ty, - }, - ConstProjectionEq { - projection: ProjectionTerm, - val: Const, + term: Term, }, - LifetimeOutlives { a: Lifetime, b: Lifetime, @@ -479,20 +480,47 @@ pub enum WhereClause { #[derive(Clone, PartialEq, Eq, Debug)] pub enum DomainGoal { - Holds { where_clause: WhereClause }, - Normalize { projection: ProjectionTerm, ty: Ty }, - TraitRefWellFormed { trait_ref: TraitRef }, - TyWellFormed { ty: Ty }, - TyFromEnv { ty: Ty }, - TraitRefFromEnv { trait_ref: TraitRef }, - IsLocal { ty: Ty }, - IsUpstream { ty: Ty }, - IsFullyVisible { ty: Ty }, - LocalImplAllowed { trait_ref: TraitRef }, + Holds { + where_clause: WhereClause, + }, + + Normalize { + projection: ProjectionTerm, + term: Term, + }, + + TraitRefWellFormed { + trait_ref: TraitRef, + }, + TyWellFormed { + ty: Ty, + }, + TyFromEnv { + ty: Ty, + }, + TraitRefFromEnv { + trait_ref: TraitRef, + }, + IsLocal { + ty: Ty, + }, + IsUpstream { + ty: Ty, + }, + IsFullyVisible { + ty: Ty, + }, + LocalImplAllowed { + trait_ref: TraitRef, + }, Compatible, - DownstreamType { ty: Ty }, + DownstreamType { + ty: Ty, + }, Reveal, - ObjectSafe { id: Identifier }, + ObjectSafe { + id: Identifier, + }, } #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index 506b5b6cea1..ce6b8bafe5d 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -593,7 +593,7 @@ WhereClause: WhereClause = { let trait_ref = TraitRef { trait_name: t, args: args }; let projection = ProjectionTerm { trait_ref, name, args: vec![] }; - WhereClause::ConstProjectionEq { projection, val } + WhereClause::ProjectionEq { projection, term: Term::Const(val) } }, // `T: Foo` -- projection equality @@ -604,7 +604,7 @@ WhereClause: WhereClause = { if let Some(a) = a { args.extend(a); } let trait_ref = TraitRef { trait_name: t, args: args }; let projection = ProjectionTerm { trait_ref, name, args: a2 }; - WhereClause::ProjectionEq { projection, ty } + WhereClause::ProjectionEq { projection, term: Term::Ty(ty) } }, // 'a: 'b @@ -647,7 +647,8 @@ DomainGoal: DomainGoal = { "FromEnv" "(" > ")" => DomainGoal::TraitRefFromEnv { trait_ref: t }, // `::U -> Bar` -- a normalization - "Normalize" "(" "->" ")" => DomainGoal::Normalize { projection: s, ty: t }, + "Normalize" "(" "->" ")" => + DomainGoal::Normalize { projection: s, term: Term::Ty(t) }, "IsLocal" "(" ")" => DomainGoal::IsLocal { ty }, "IsUpstream" "(" ")" => DomainGoal::IsUpstream { ty }, diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index 2b953639bc6..bb781bae588 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -513,7 +513,7 @@ pub fn program_clauses_that_could_match( push_alias_alias_eq_clause( builder, proj.clone(), - alias_eq.ty.clone(), + alias_eq.term.clone(), alias.clone(), ); return Ok(clauses); @@ -531,7 +531,7 @@ pub fn program_clauses_that_could_match( _ => {} } - db.associated_ty_data(proj.associated_term_id) + db.associated_term_data(proj.associated_term_id) .to_program_clauses(builder, environment) } AliasTy::Opaque(opaque_ty) => db @@ -570,9 +570,6 @@ pub fn program_clauses_that_could_match( }) }); } - DomainGoal::Holds(WhereClause::ConstEq(const_eq)) => { - todo!() - } DomainGoal::WellFormed(WellFormed::Trait(trait_ref)) | DomainGoal::LocalImplAllowed(trait_ref) => { db.trait_datum(trait_ref.trait_id) @@ -589,7 +586,7 @@ pub fn program_clauses_that_could_match( | DomainGoal::IsFullyVisible(ty) | DomainGoal::IsLocal(ty) => match_ty(builder, environment, ty)?, DomainGoal::FromEnv(_) => (), // Computed in the environment - DomainGoal::Normalize(Normalize { alias, ty: _ }) => match alias { + DomainGoal::Normalize(Normalize { alias, term: _ }) => match alias { AliasTy::Projection(proj) => { // Normalize goals derive from `AssociatedTyValue` datums, // which are found in impls. That is, if we are @@ -602,7 +599,7 @@ pub fn program_clauses_that_could_match( // type Item = Bar; // <-- associated type value // } // ``` - let associated_ty_datum = db.associated_ty_data(proj.associated_term_id); + let associated_ty_datum = db.associated_term_data(proj.associated_term_id); let trait_id = associated_ty_datum.trait_id; let trait_parameters = db.trait_parameters_from_projection(proj); @@ -687,7 +684,7 @@ fn push_clauses_for_compatible_normalize( for i in 0..type_parameters.len() { builder.push_clause( DomainGoal::Normalize(Normalize { - ty: target_ty.clone(), + term: Term::Ty(target_ty.clone()), alias: AliasTy::Projection(projection.clone()), }), where_clauses @@ -744,8 +741,8 @@ fn push_program_clauses_for_associated_type_values_in_impls_of( debug!(?impl_id); - for &atv_id in &impl_datum.associated_ty_value_ids { - let atv = builder.db.associated_ty_value(atv_id); + for &atv_id in &impl_datum.associated_term_value_ids { + let atv = builder.db.associated_term_value(atv_id); debug!(?atv_id, ?atv); atv.to_program_clauses(builder, environment); } @@ -800,19 +797,19 @@ fn push_alias_implemented_clause( fn push_alias_alias_eq_clause( builder: &mut ClauseBuilder<'_, I>, - projection_ty: ProjectionTerm, - ty: Ty, + projection_term: ProjectionTerm, + term: Term, alias: AliasTy, ) { let interner = builder.interner(); assert_eq!( - *projection_ty.self_type_parameter(interner).kind(interner), + *projection_term.self_type_parameter(interner).kind(interner), TyKind::Alias(alias.clone()) ); // TODO: instead generate clauses without reference to the specific type parameters of the goal? - let generalized = generalize::Generalize::apply(interner, (projection_ty, ty, alias)); - builder.push_binders(generalized, |builder, (projection_ty, ty, alias)| { + let generalized = generalize::Generalize::apply(interner, (projection_term, term, alias)); + builder.push_binders(generalized, |builder, (projection_term, term, alias)| { let binders = Binders::with_fresh_type_var(interner, |ty_var| ty_var); // forall<..., T> { @@ -822,7 +819,7 @@ fn push_alias_alias_eq_clause( let fresh_self_subst = Substitution::from_iter( interner, std::iter::once(bound_var.clone().cast(interner)).chain( - projection_ty.substitution.as_slice(interner)[1..] + projection_term.substitution.as_slice(interner)[1..] .iter() .cloned(), ), @@ -834,16 +831,16 @@ fn push_alias_alias_eq_clause( builder.push_clause( DomainGoal::Holds(WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty.clone()), - ty: ty.clone(), + term: term.clone(), })), &[ DomainGoal::Holds(WhereClause::AliasEq(AliasEq { alias: fresh_alias, - ty: ty.clone(), + term: term.clone(), })), DomainGoal::Holds(WhereClause::AliasEq(AliasEq { alias: alias.clone(), - ty: bound_var, + term: bound_var, })), ], ); @@ -883,7 +880,7 @@ fn match_ty( TyKind::Error => {} TyKind::AssociatedType(type_id, _) => builder .db - .associated_ty_data(*type_id) + .associated_term_data(*type_id) .to_program_clauses(builder, environment), TyKind::FnDef(fn_def_id, _) => builder .db @@ -1036,7 +1033,7 @@ fn match_ty( } TyKind::Alias(AliasTy::Projection(proj)) => builder .db - .associated_ty_data(proj.associated_term_id) + .associated_term_data(proj.associated_term_id) .to_program_clauses(builder, environment), TyKind::Alias(AliasTy::Opaque(opaque_ty)) => builder .db @@ -1074,7 +1071,6 @@ fn match_ty( vec![DomainGoal::WellFormed(WellFormed::Trait(trait_ref.clone()))] } WhereClause::AliasEq(_) - | WhereClause::ConstEq(_) | WhereClause::LifetimeOutlives(_) | WhereClause::TypeOutlives(_) => vec![], } @@ -1096,7 +1092,7 @@ fn match_alias_ty( if let AliasTy::Projection(projection_term) = alias { builder .db - .associated_ty_data(projection_term.associated_term_id) + .associated_term_data(projection_term.associated_term_id) .to_program_clauses(builder, environment) } } diff --git a/chalk-solve/src/clauses/builder.rs b/chalk-solve/src/clauses/builder.rs index de63f33dabc..48e0f7346eb 100644 --- a/chalk-solve/src/clauses/builder.rs +++ b/chalk-solve/src/clauses/builder.rs @@ -201,6 +201,28 @@ impl<'me, I: Interner> ClauseBuilder<'me, I> { }); } + /// Push a single binder, for a const, at the end of the binder + /// list. The indices of previously bound variables are + /// unaffected and hence the context remains usable. Invokes `op`, + /// passing a const representing this new const variable in as an + /// argument. + pub fn push_bound_const(&mut self, ty: Ty, op: impl FnOnce(&mut Self, Const)) { + let interner = self.interner(); + let binders = Binders::new( + VariableKinds::from1(interner, VariableKind::Const(ty)), + PhantomData::, + ); + self.push_binders(binders, |this, PhantomData| { + let ct = this + .placeholders_in_scope() + .last() + .unwrap() + .assert_const_ref(interner) + .clone(); + op(this, lifetime) + }); + } + pub fn interner(&self) -> I { self.db.interner() } diff --git a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs index 3cb440247a8..8fb97c3202d 100644 --- a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs +++ b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs @@ -2,6 +2,7 @@ use crate::clauses::ClauseBuilder; use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait}; use chalk_ir::{ AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Ty, TyKind, TyVariableKind, + Term, }; pub fn add_discriminant_clauses( @@ -63,7 +64,7 @@ pub fn add_discriminant_clauses( associated_term_id: associated_ty_id, substitution, }), - ty: disc_ty, + term: Term::Ty(disc_ty), }; builder.push_fact(trait_ref); diff --git a/chalk-solve/src/clauses/builtin_traits/fn_family.rs b/chalk-solve/src/clauses/builtin_traits/fn_family.rs index 9dace598f0e..cd261526ab0 100644 --- a/chalk-solve/src/clauses/builtin_traits/fn_family.rs +++ b/chalk-solve/src/clauses/builtin_traits/fn_family.rs @@ -4,6 +4,7 @@ use crate::{Interner, RustIrDatabase, TraitRef}; use chalk_ir::cast::Cast; use chalk_ir::{ AliasTy, Binders, Normalize, ProjectionTerm, Safety, Substitution, TraitId, Ty, TyKind, + Term, }; fn push_clauses( @@ -42,7 +43,7 @@ fn push_clauses( }); builder.push_fact(Normalize { alias, - ty: return_type, + term: Term::Ty(return_type), }); } } diff --git a/chalk-solve/src/clauses/builtin_traits/generator.rs b/chalk-solve/src/clauses/builtin_traits/generator.rs index 979614e7472..80ab7c59677 100644 --- a/chalk-solve/src/clauses/builtin_traits/generator.rs +++ b/chalk-solve/src/clauses/builtin_traits/generator.rs @@ -2,7 +2,7 @@ use crate::clauses::ClauseBuilder; use crate::rust_ir::WellKnownTrait; use crate::{Interner, RustIrDatabase, TraitRef}; use chalk_ir::cast::Cast; -use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Ty, TyKind}; +use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Ty, TyKind, Term}; /// Add implicit impls of the generator trait, i.e., add a clause that all generators implement /// `Generator` and clauses for `Generator`'s associated types. @@ -52,7 +52,7 @@ pub fn add_generator_program_clauses( }); builder.push_fact(Normalize { alias: yield_alias, - ty: generator_io_datum.yield_type, + term: Term::Ty(generator_io_datum.yield_type), }); // `Generator::Return` @@ -63,7 +63,7 @@ pub fn add_generator_program_clauses( }); builder.push_fact(Normalize { alias: return_alias, - ty: generator_io_datum.return_type, + term: Term::Ty(generator_io_datum.return_type), }); Ok(()) diff --git a/chalk-solve/src/clauses/dyn_ty.rs b/chalk-solve/src/clauses/dyn_ty.rs index efb778c6746..505da43f972 100644 --- a/chalk-solve/src/clauses/dyn_ty.rs +++ b/chalk-solve/src/clauses/dyn_ty.rs @@ -72,7 +72,7 @@ pub(super) fn build_dyn_self_ty_clauses( ) } // FIXME: Associated item bindings are just taken as facts (?) - WhereClause::AliasEq(_) | WhereClause::ConstEq(_) => builder.push_fact(bound), + WhereClause::AliasEq(_) => builder.push_fact(bound), WhereClause::LifetimeOutlives(..) => {} WhereClause::TypeOutlives(..) => {} }); diff --git a/chalk-solve/src/clauses/env_elaborator.rs b/chalk-solve/src/clauses/env_elaborator.rs index 3c490258029..3d13605795c 100644 --- a/chalk-solve/src/clauses/env_elaborator.rs +++ b/chalk-solve/src/clauses/env_elaborator.rs @@ -91,9 +91,9 @@ impl<'me, 'builder, I: Interner> Visitor for EnvElaborator<'me, 'builder, I> // If we know that `T: Iterator`, then we also know // things about `::Item`, so push those // implied bounds too: - for &associated_ty_id in &trait_datum.associated_ty_ids { + for &ai in &trait_datum.associated_ty_ids { self.db - .associated_ty_data(associated_ty_id) + .associated_term_data(ai) .to_program_clauses(self.builder, self.environment); } ControlFlow::Continue(()) diff --git a/chalk-solve/src/clauses/program_clauses.rs b/chalk-solve/src/clauses/program_clauses.rs index 80faf55ae22..a6f2b837409 100644 --- a/chalk-solve/src/clauses/program_clauses.rs +++ b/chalk-solve/src/clauses/program_clauses.rs @@ -49,7 +49,7 @@ impl ToProgramClauses for ImplDatum { } } -impl ToProgramClauses for AssociatedTyValue { +impl ToProgramClauses for AssociatedTermValue { /// Given the following trait: /// /// ```notrust @@ -81,7 +81,7 @@ impl ToProgramClauses for AssociatedTyValue { _environment: &Environment, ) { let impl_datum = builder.db.impl_datum(self.impl_id); - let associated_ty = builder.db.associated_ty_data(self.associated_ty_id); + let associated_ty = builder.db.associated_term_data(self.associated_term_id); builder.push_binders(self.value.clone(), |builder, assoc_ty_value| { let all_parameters = builder.placeholders_in_scope().to_vec(); @@ -126,7 +126,10 @@ impl ToProgramClauses for AssociatedTyValue { builder.push_clause( Normalize { alias: AliasTy::Projection(projection.clone()), - ty: assoc_ty_value.ty, + term: match assoc_ty_value { + AssociatedTermValueBound::Ty(ty) => Term::Ty(ty), + AssociatedTermValueBound::Const(ct) => Term::Const(ct), + }, }, impl_where_clauses.chain(assoc_ty_where_clauses), ); @@ -206,7 +209,7 @@ impl ToProgramClauses for OpaqueTyDatum { ) } // FIXME: Associated item bindings are just taken as facts (?) - WhereClause::AliasEq(_) | WhereClause::ConstEq(_) => builder.push_fact(bound), + WhereClause::AliasEq(_) => builder.push_fact(bound), WhereClause::LifetimeOutlives(..) => {} WhereClause::TypeOutlives(..) => {} }); @@ -722,7 +725,7 @@ impl ToProgramClauses for TraitDatum { } } -impl ToProgramClauses for AssociatedTyDatum { +impl ToProgramClauses for AssociatedTermDatum { /// For each associated type, we define the "projection /// equality" rules. There are always two; one for a successful normalization, /// and one for the "fallback" notion of equality. @@ -801,7 +804,7 @@ impl ToProgramClauses for AssociatedTyDatum { builder.push_binders( binders, |builder, - AssociatedTyDatumBound { + AssociatedTermDatumBound { where_clauses, bounds, }| { @@ -898,7 +901,7 @@ impl ToProgramClauses for AssociatedTyDatum { // `Normalize(::Assoc -> U)` let normalize = Normalize { alias: AliasTy::Projection(projection.clone()), - ty: ty.clone(), + term: Term::Ty(ty.clone()), }; // `AliasEq(::Assoc = U)` diff --git a/chalk-solve/src/clauses/super_traits.rs b/chalk-solve/src/clauses/super_traits.rs index 13005d9b8d5..7e99b8fc134 100644 --- a/chalk-solve/src/clauses/super_traits.rs +++ b/chalk-solve/src/clauses/super_traits.rs @@ -95,7 +95,6 @@ pub fn super_traits( } WhereClause::AliasEq(_) | WhereClause::LifetimeOutlives(..) - | WhereClause::ConstEq(_) | WhereClause::TypeOutlives(..) => None, }) }) diff --git a/chalk-solve/src/coinductive_goal.rs b/chalk-solve/src/coinductive_goal.rs index 9198b28694f..4b3ef490c54 100644 --- a/chalk-solve/src/coinductive_goal.rs +++ b/chalk-solve/src/coinductive_goal.rs @@ -25,8 +25,7 @@ impl IsCoinductive for Goal { } WhereClause::AliasEq(_) | WhereClause::LifetimeOutlives(..) - | WhereClause::TypeOutlives(..) - | WhereClause::ConstEq(_) => false, + | WhereClause::TypeOutlives(..) => false, }, GoalData::DomainGoal(DomainGoal::WellFormed(WellFormed::Trait(..))) => true, GoalData::Quantified(QuantifierKind::ForAll, goal) => { diff --git a/chalk-solve/src/display.rs b/chalk-solve/src/display.rs index 4c357bdb209..d6e81d0c69e 100644 --- a/chalk-solve/src/display.rs +++ b/chalk-solve/src/display.rs @@ -165,7 +165,6 @@ fn display_self_where_clauses_as_bounds<'a, I: Interner>( } AliasTy::Opaque(opaque) => opaque.display(s).fmt(f), }, - WhereClause::ConstEq(_) => todo!(), WhereClause::LifetimeOutlives(lifetime) => lifetime.display(s).fmt(f), WhereClause::TypeOutlives(ty) => ty.display(s).fmt(f), } @@ -199,7 +198,7 @@ fn display_type_with_generics<'a, I: Interner>( /// This is shared between where bounds & dyn Trait. fn display_trait_with_assoc_ty_value<'a, I: Interner>( s: &'a InternalWriterState<'a, I>, - assoc_ty_datum: Arc>, + assoc_ty_datum: Arc>, trait_params: &'a [GenericArg], assoc_ty_params: &'a [GenericArg], assoc_ty_value: &'a Ty, diff --git a/chalk-solve/src/display/bounds.rs b/chalk-solve/src/display/bounds.rs index 33305a81184..e33b7366f14 100644 --- a/chalk-solve/src/display/bounds.rs +++ b/chalk-solve/src/display/bounds.rs @@ -34,7 +34,7 @@ impl RenderAsRust for AliasEqBound { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { display_trait_with_assoc_ty_value( s, - s.db().associated_ty_data(self.associated_ty_id), + s.db().associated_term_data(self.associated_ty_id), &self.trait_bound.args_no_self, &self.parameters, &self.value, @@ -91,7 +91,6 @@ impl RenderAsRust for WhereClause { match self { WhereClause::Implemented(trait_ref) => trait_ref.fmt(s, f), WhereClause::AliasEq(alias_eq) => alias_eq.fmt(s, f), - WhereClause::ConstEq(const_eq) => const_eq.fmt(s, f), WhereClause::LifetimeOutlives(lifetime) => lifetime.display(s).fmt(f), WhereClause::TypeOutlives(ty) => ty.display(s).fmt(f), } @@ -154,12 +153,6 @@ impl RenderAsRust for AliasEq { } } -impl RenderAsRust for ConstEq { - fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - todo!() - } -} - impl RenderAsRust for LifetimeOutlives { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { // a': 'b diff --git a/chalk-solve/src/display/items.rs b/chalk-solve/src/display/items.rs index 78ebbfac184..5cee89d89cd 100644 --- a/chalk-solve/src/display/items.rs +++ b/chalk-solve/src/display/items.rs @@ -228,8 +228,8 @@ impl RenderAsRust for TraitDatum { write_joined_non_empty_list!( f, "\n{}\n", - self.associated_ty_ids.iter().map(|assoc_ty_id| { - let assoc_ty_data = s.db().associated_ty_data(*assoc_ty_id); + self.associated_ty_ids.iter().map(|assoc_id| { + let assoc_ty_data = s.db().associated_term_data(*assoc_id); format!("{}{}", s.indent(), (*assoc_ty_data).display(s)) }), "\n" @@ -299,9 +299,9 @@ impl RenderAsRust for ImplDatum { write!(f, "{{")?; { let s = &s.add_indent(); - let assoc_ty_values = self.associated_ty_value_ids.iter().map(|assoc_ty_value| { + let assoc_ty_values = self.associated_term_value_ids.iter().map(|av| { s.db() - .associated_ty_value(*assoc_ty_value) + .associated_term_value(*av) .display(s) .to_string() }); @@ -336,14 +336,14 @@ impl RenderAsRust for OpaqueTyDatum { } } -impl RenderAsRust for AssociatedTyDatum { +impl RenderAsRust for AssociatedTermDatum { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { // In lowering, a completely new empty environment is created for each - // AssociatedTyDatum, and it's given generic parameters for each generic + // AssociatedTermDatum, and it's given generic parameters for each generic // parameter that its trait had. We want to map the new binders for // those generic parameters back into their original names. To do that, // first find their original names (trait_binder_names), then the names - // they have inside the AssociatedTyDatum (assoc_ty_names_for_trait_params), + // they have inside the AssociatedTermDatum (assoc_ty_names_for_trait_params), // and then add that mapping to the WriterState when writing bounds and // where clauses. let trait_datum = s.db().trait_datum(self.trait_id); @@ -409,11 +409,11 @@ impl RenderAsRust for AssociatedTyDatum { } } -impl RenderAsRust for AssociatedTyValue { +impl RenderAsRust for AssociatedTermValue { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { - // see comments for a similar empty env operation in AssociatedTyDatum's + // see comments for a similar empty env operation in AssociatedTermDatum's // impl of RenderAsRust. - let assoc_ty_data = s.db().associated_ty_data(self.associated_ty_id); + let assoc_ty_data = s.db().associated_term_data(self.associated_term_id); let impl_datum = s.db().impl_datum(self.impl_id); let impl_param_names_in_impl_env = s.binder_var_indices(&impl_datum.binders.binders); @@ -444,7 +444,10 @@ impl RenderAsRust for AssociatedTyValue { write!(f, "{}type {}", s.indent(), assoc_ty_data.id.display(s))?; write_joined_non_empty_list!(f, "<{}>", assoc_ty_value_display, ", ")?; - write!(f, " = {};", value.ty.display(s))?; + match value { + AssociatedTermValueBound::Ty(ty) => write!(f, " = {};", ty.display(s))?, + AssociatedTermValueBound::Const(ct) => write!(f, " = const {};", ct.display(s))?, + } Ok(()) } } diff --git a/chalk-solve/src/display/stub.rs b/chalk-solve/src/display/stub.rs index 64968ab1658..94c83fb5ff8 100644 --- a/chalk-solve/src/display/stub.rs +++ b/chalk-solve/src/display/stub.rs @@ -5,7 +5,7 @@ use std::sync::Arc; use crate::rust_ir::{GeneratorDatum, GeneratorWitnessDatum}; use crate::{ rust_ir::{ - AdtDatumBound, AdtKind, AdtVariantDatum, AssociatedTyDatumBound, FnDefDatumBound, + AdtDatumBound, AdtKind, AdtVariantDatum, AssociatedTermDatumBound, FnDefDatumBound, OpaqueTyDatumBound, TraitDatumBound, }, RustIrDatabase, @@ -41,14 +41,14 @@ impl> RustIrDatabase for StubWrapper<'_, D self.db.custom_clauses() } - fn associated_ty_data( + fn associated_term_data( &self, ty: chalk_ir::AssocItemId, - ) -> Arc> { - let mut v = (*self.db.associated_ty_data(ty)).clone(); + ) -> Arc> { + let mut v = (*self.db.associated_term_data(ty)).clone(); v.binders = Binders::new( v.binders.binders.clone(), - AssociatedTyDatumBound { + AssociatedTermDatumBound { where_clauses: Vec::new(), bounds: Vec::new(), }, @@ -56,13 +56,6 @@ impl> RustIrDatabase for StubWrapper<'_, D Arc::new(v) } - fn associated_const_data( - &self, - ct: chalk_ir::AssocItemId, - ) -> Arc> { - Arc::new((*self.db.associated_const_data(ct)).clone()) - } - fn trait_datum( &self, trait_id: chalk_ir::TraitId, @@ -123,10 +116,10 @@ impl> RustIrDatabase for StubWrapper<'_, D unreachable!("impl items should never be stubbed") } - fn associated_ty_value( + fn associated_term_value( &self, - _id: crate::rust_ir::AssociatedTyValueId, - ) -> std::sync::Arc> { + _id: crate::rust_ir::AssociatedTermValueId, + ) -> std::sync::Arc> { unreachable!("associated type values should never be stubbed") } diff --git a/chalk-solve/src/display/ty.rs b/chalk-solve/src/display/ty.rs index 2f363663368..87a6efff88d 100644 --- a/chalk-solve/src/display/ty.rs +++ b/chalk-solve/src/display/ty.rs @@ -22,10 +22,10 @@ impl RenderAsRust for TyKind { let parameters = parameters.iter().map(|param| param.display(s)); write_joined_non_empty_list!(f, "<{}>", parameters, ", ") } - TyKind::AssociatedType(assoc_type_id, substitution) => { + TyKind::AssociatedType(assoc_id, substitution) => { // (Iterator::Item)(x) // should be written in Rust as ::Item - let datum = s.db().associated_ty_data(*assoc_type_id); + let datum = s.db().associated_term_data(*assoc_id); assert!( substitution .iter(interner) diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index 4845d03ad07..9c1782ea5ce 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -672,9 +672,6 @@ impl<'t, I: Interner> Unifier<'t, I> { self.table.new_variable(universe_index).to_ty(interner); WhereClause::AliasEq(AliasEq { alias, ty }) } - WhereClause::ConstEq(ConstEq { term, ct }) => { - todo!(); - } WhereClause::TypeOutlives(_) => { let lifetime_var = self.table.new_variable(universe_index); let lifetime = lifetime_var.to_lifetime(interner); diff --git a/chalk-solve/src/lib.rs b/chalk-solve/src/lib.rs index 2bd7c9aeb42..30f7e42072f 100644 --- a/chalk-solve/src/lib.rs +++ b/chalk-solve/src/lib.rs @@ -47,10 +47,7 @@ pub trait RustIrDatabase: Debug { fn custom_clauses(&self) -> Vec>; /// Returns the datum for the associated type with the given id. - fn associated_ty_data(&self, ty: AssocItemId) -> Arc>; - - /// Returns the datum for the associated type with the given id. - fn associated_const_data(&self, ty: AssocItemId) -> Arc>; + fn associated_term_data(&self, ty: AssocItemId) -> Arc>; /// Returns the datum for the definition with the given id. fn trait_datum(&self, trait_id: TraitId) -> Arc>; @@ -79,8 +76,8 @@ pub trait RustIrDatabase: Debug { /// Returns the datum for the impl with the given id. fn impl_datum(&self, impl_id: ImplId) -> Arc>; - /// Returns the `AssociatedTyValue` with the given id. - fn associated_ty_value(&self, id: AssociatedTyValueId) -> Arc>; + /// Returns the `AssociatedTermValue` with the given id. + fn associated_term_value(&self, id: AssociatedTermValueId) -> Arc>; /// Returns the `OpaqueTyDatum` with the given id. fn opaque_ty_data(&self, id: OpaqueTyId) -> Arc>; diff --git a/chalk-solve/src/logging_db.rs b/chalk-solve/src/logging_db.rs index b50b279a987..d90eff08484 100644 --- a/chalk-solve/src/logging_db.rs +++ b/chalk-solve/src/logging_db.rs @@ -119,24 +119,15 @@ where self.ws.db().custom_clauses() } - fn associated_ty_data( + fn associated_term_data( &self, ty: chalk_ir::AssocItemId, - ) -> Arc> { - let ty_datum = self.ws.db().associated_ty_data(ty); + ) -> Arc> { + let ty_datum = self.ws.db().associated_term_data(ty); self.record(ty_datum.trait_id); ty_datum } - fn associated_const_data( - &self, - ct: chalk_ir::AssocItemId, - ) -> Arc> { - let ct_datum = self.ws.db().associated_const_data(ct); - self.record(ct_datum.trait_id); - ct_datum - } - fn trait_datum(&self, trait_id: TraitId) -> Arc> { self.record(trait_id); self.ws.db().trait_datum(trait_id) @@ -180,11 +171,11 @@ where self.ws.db().hidden_opaque_type(id) } - fn associated_ty_value( + fn associated_term_value( &self, - id: crate::rust_ir::AssociatedTyValueId, - ) -> Arc> { - let value = self.ws.db().associated_ty_value(id); + id: crate::rust_ir::AssociatedTermValueId, + ) -> Arc> { + let value = self.ws.db().associated_term_value(id); self.record(value.impl_id); value } @@ -404,18 +395,11 @@ where self.db.custom_clauses() } - fn associated_ty_data( + fn associated_term_data( &self, ty: chalk_ir::AssocItemId, - ) -> Arc> { - self.db.associated_ty_data(ty) - } - - fn associated_const_data( - &self, - ct: chalk_ir::AssocItemId, - ) -> Arc> { - self.db.associated_const_data(ct) + ) -> Arc> { + self.db.associated_term_data(ty) } fn trait_datum(&self, trait_id: TraitId) -> Arc> { @@ -450,11 +434,11 @@ where self.db.impl_datum(impl_id) } - fn associated_ty_value( + fn associated_term_value( &self, - id: crate::rust_ir::AssociatedTyValueId, - ) -> Arc> { - self.db.associated_ty_value(id) + id: crate::rust_ir::AssociatedTermValueId, + ) -> Arc> { + self.db.associated_term_value(id) } fn opaque_ty_data(&self, id: OpaqueTyId) -> Arc> { diff --git a/chalk-solve/src/logging_db/id_collector.rs b/chalk-solve/src/logging_db/id_collector.rs index 947ef3e145f..5992b62d0d8 100644 --- a/chalk-solve/src/logging_db/id_collector.rs +++ b/chalk-solve/src/logging_db/id_collector.rs @@ -61,7 +61,7 @@ pub fn collect_unrecorded_ids>( trait_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST); for assoc_ty_id in &trait_datum.associated_ty_ids { - let assoc_ty_datum = collector.db.associated_ty_data(*assoc_ty_id); + let assoc_ty_datum = collector.db.associated_term_data(*assoc_ty_id); assoc_ty_datum .bounds_on_self(collector.db.interner()) .visit_with(&mut collector, DebruijnIndex::INNERMOST); @@ -80,8 +80,8 @@ pub fn collect_unrecorded_ids>( } RecordedItemId::Impl(impl_id) => { let impl_datum = collector.db.impl_datum(impl_id); - for id in &impl_datum.associated_ty_value_ids { - let assoc_ty_value = collector.db.associated_ty_value(*id); + for id in &impl_datum.associated_term_value_ids { + let assoc_ty_value = collector.db.associated_term_value(*id); assoc_ty_value.visit_with(&mut collector, DebruijnIndex::INNERMOST); } impl_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST); @@ -108,7 +108,7 @@ impl<'i, I: Interner, DB: RustIrDatabase> IdCollector<'i, I, DB> { fn visit_alias(&mut self, alias: &AliasTy) { match alias { AliasTy::Projection(projection_ty) => { - let assoc_ty_datum = self.db.associated_ty_data(projection_ty.associated_term_id); + let assoc_ty_datum = self.db.associated_term_data(projection_ty.associated_term_id); self.record(assoc_ty_datum.trait_id) } AliasTy::Opaque(opaque_ty) => self.record(opaque_ty.opaque_ty_id), @@ -154,10 +154,6 @@ impl<'i, I: Interner, DB: RustIrDatabase> Visitor for IdCollector<'i, I, D match where_clause { WhereClause::Implemented(trait_ref) => self.record(trait_ref.trait_id), WhereClause::AliasEq(alias_eq) => self.visit_alias(&alias_eq.alias), - WhereClause::ConstEq(const_eq) => { - self.db.associated_const_data(const_eq.term); - self.visit_const(&const_eq.ct, outer_binder)?; - } WhereClause::LifetimeOutlives(_lifetime_outlives) => (), WhereClause::TypeOutlives(_type_outlives) => (), } diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index 2dab2810ea6..b570135f1a8 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -9,32 +9,24 @@ use chalk_ir::interner::Interner; use chalk_ir::{ try_break, visit::Visit, AdtId, AliasEq, AliasTy, AssocItemId, Binders, DebruijnIndex, FnDefId, GenericArg, ImplId, OpaqueTyId, ProjectionTerm, QuantifiedWhereClause, Substitution, - ToGenericArg, TraitId, TraitRef, Ty, TyKind, VariableKind, WhereClause, WithKind, + ToGenericArg, TraitId, TraitRef, Ty, TyKind, Const, VariableKind, WhereClause, WithKind, }; use std::iter; use std::ops::ControlFlow; -/// Identifier for an "associated type value" found in some impl. +/// Identifier for an "associated term value" found in some impl. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct AssociatedTyValueId(pub I::DefId); +pub struct AssociatedTermValueId(pub I::DefId); -/// Identifier for an "associated const value" found in some impl. -#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct AssociatedConstValueId(pub I::DefId); - -chalk_ir::id_visit!(AssociatedTyValueId); -chalk_ir::id_fold!(AssociatedTyValueId); - -chalk_ir::id_visit!(AssociatedConstValueId); -chalk_ir::id_fold!(AssociatedConstValueId); +chalk_ir::id_visit!(AssociatedTermValueId); +chalk_ir::id_fold!(AssociatedTermValueId); #[derive(Clone, Debug, PartialEq, Eq, Hash, Visit)] pub struct ImplDatum { pub polarity: Polarity, pub binders: Binders>, pub impl_type: ImplType, - pub associated_ty_value_ids: Vec>, - pub associated_const_value_ids: Vec>, + pub associated_term_value_ids: Vec>, } impl ImplDatum { @@ -493,7 +485,7 @@ impl Anonymize for [WithKind] { /// * The *where clauses* `where_clauses` are things that the impl can *assume* to be true /// (but which projectors must prove). #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct AssociatedTyDatum { +pub struct AssociatedTermDatum { /// The trait this associated type is defined in. pub trait_id: TraitId, @@ -508,11 +500,11 @@ pub struct AssociatedTyDatum { /// from `Bar` come first (corresponding to the de bruijn concept /// that "inner" binders are lower indices, although within a /// given binder we do not have an ordering). - pub binders: Binders>, + pub binders: Binders>, } // Manual implementation to avoid I::Identifier type. -impl Visit for AssociatedTyDatum { +impl Visit for AssociatedTermDatum { fn visit_with( &self, visitor: &mut dyn chalk_ir::visit::Visitor, @@ -524,34 +516,10 @@ impl Visit for AssociatedTyDatum { } } -#[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub struct AssociatedConstDatum { - /// The trait this associated type is defined in. - pub trait_id: TraitId, - - /// The ID of this associated type - pub id: AssocItemId, - - /// Name of this associated type. - pub name: I::Identifier, -} - -// Manual implementation to avoid I::Identifier type. -impl Visit for AssociatedConstDatum { - fn visit_with( - &self, - visitor: &mut dyn chalk_ir::visit::Visitor, - outer_binder: DebruijnIndex, - ) -> ControlFlow { - try_break!(self.trait_id.visit_with(visitor, outer_binder)); - self.id.visit_with(visitor, outer_binder) - } -} - -/// Encodes the parts of `AssociatedTyDatum` where the parameters +/// Encodes the parts of `AssociatedTermDatum` where the parameters /// `P0..Pm` are in scope (`bounds` and `where_clauses`). #[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)] -pub struct AssociatedTyDatumBound { +pub struct AssociatedTermDatumBound { /// Bounds on the associated type itself. /// /// These must be proven by the implementer, for all possible parameters that @@ -562,7 +530,7 @@ pub struct AssociatedTyDatumBound { pub where_clauses: Vec>, } -impl AssociatedTyDatum { +impl AssociatedTermDatum { /// Returns the associated ty's bounds applied to the projection type, e.g.: /// /// ```notrust @@ -613,7 +581,7 @@ impl AssociatedTyDatum { /// } /// ``` #[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)] -pub struct AssociatedTyValue { +pub struct AssociatedTermValue { /// Impl in which this associated type value is found. You might /// need to look at this to find the generic parameters defined on /// the impl, for example. @@ -636,7 +604,7 @@ pub struct AssociatedTyValue { /// type Item; // <-- refers to this declaration here! /// } /// ``` - pub associated_ty_id: AssocItemId, + pub associated_term_id: AssocItemId, /// Additional binders declared on the associated type itself, /// beyond those from the impl. This would be empty for normal @@ -648,40 +616,13 @@ pub struct AssociatedTyValue { /// // ^^^^ refers to these generics here /// } /// ``` - pub value: Binders>, -} - -#[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit)] -pub struct AssociatedConstValue { - /// Impl in which this associated type value is found. You might - /// need to look at this to find the generic parameters defined on - /// the impl, for example. - /// - /// ```ignore - /// impl Iterator for Foo { // <-- refers to this impl - /// const Item: usize = XXX; // <-- (where this is self) - /// } - /// ``` - pub impl_id: ImplId, - - /// Associated type being defined. - /// - /// ```ignore - /// impl Iterator for Foo { - /// const Item: usize = XXX; // <-- (where this is self) - /// } - /// ... - /// trait Iterator { - /// const Item: usize; // <-- refers to this declaration here! - /// } - /// ``` - pub associated_const_id: AssocItemId, + pub value: Binders>, } #[derive(Clone, Debug, PartialEq, Eq, Hash, Fold, Visit, HasInterner)] -pub struct AssociatedTyValueBound { - /// Type that we normalize to. The X in `type Foo<'a> = X`. - pub ty: Ty, +pub enum AssociatedTermValueBound { + Ty(Ty), + Const(Const), } /// Represents the bounds for an `impl Trait` type. diff --git a/chalk-solve/src/split.rs b/chalk-solve/src/split.rs index c286dc60985..a46cc5668c6 100644 --- a/chalk-solve/src/split.rs +++ b/chalk-solve/src/split.rs @@ -18,7 +18,7 @@ pub trait Split: RustIrDatabase { &self, projection: &'p ProjectionTerm, ) -> ( - Arc>, + Arc>, &'p [GenericArg], &'p [GenericArg], ) { @@ -28,7 +28,7 @@ pub trait Split: RustIrDatabase { ref substitution, } = *projection; let parameters = substitution.as_slice(interner); - let associated_ty_data = &self.associated_ty_data(associated_term_id); + let associated_ty_data = &self.associated_term_data(associated_term_id); let (trait_params, other_params) = self.split_associated_ty_parameters(parameters, &**associated_ty_data); (associated_ty_data.clone(), trait_params, other_params) @@ -83,7 +83,7 @@ pub trait Split: RustIrDatabase { fn split_associated_ty_value_parameters<'p, P>( &self, parameters: &'p [P], - associated_ty_value: &AssociatedTyValue, + associated_ty_value: &AssociatedTermValue, ) -> (&'p [P], &'p [P]) { let interner = self.interner(); let impl_datum = self.impl_datum(associated_ty_value.impl_id); @@ -123,7 +123,7 @@ pub trait Split: RustIrDatabase { fn impl_parameters_and_projection_from_associated_ty_value<'p>( &self, parameters: &'p [GenericArg], - associated_ty_value: &AssociatedTyValue, + associated_ty_value: &AssociatedTermValue, ) -> (&'p [GenericArg], ProjectionTerm) { let interner = self.interner(); @@ -151,7 +151,7 @@ pub trait Split: RustIrDatabase { ); let projection = ProjectionTerm { - associated_term_id: associated_ty_value.associated_ty_id, + associated_term_id: associated_ty_value.associated_term_id, substitution: projection_substitution, }; @@ -186,7 +186,7 @@ pub trait Split: RustIrDatabase { fn split_associated_ty_parameters<'p, P>( &self, parameters: &'p [P], - associated_ty_datum: &AssociatedTyDatum, + associated_ty_datum: &AssociatedTermDatum, ) -> (&'p [P], &'p [P]) { let trait_datum = &self.trait_datum(associated_ty_datum.trait_id); let trait_num_params = trait_datum.binders.len(self.interner()); diff --git a/chalk-solve/src/wf.rs b/chalk-solve/src/wf.rs index a169bfe14ef..9aed23e76ba 100644 --- a/chalk-solve/src/wf.rs +++ b/chalk-solve/src/wf.rs @@ -90,10 +90,6 @@ impl Visitor for InputTypeCollector { .clone() .intern(self.interner) .visit_with(self, outer_binder), - WhereClause::ConstEq(const_eq) => { - const_eq.term.visit_with(self, outer_binder)?; - const_eq.ct.visit_with(self, outer_binder) - } WhereClause::Implemented(trait_ref) => trait_ref.visit_with(self, outer_binder), WhereClause::TypeOutlives(TypeOutlives { ty, .. }) => ty.visit_with(self, outer_binder), WhereClause::LifetimeOutlives(..) => ControlFlow::Continue(()), @@ -324,7 +320,7 @@ where interner, impl_header_wf_goal(self.db, impl_id).into_iter().chain( impl_datum - .associated_ty_value_ids + .associated_term_value_ids .iter() .filter_map(|&id| compute_assoc_ty_goal(self.db, id)), ), @@ -562,26 +558,29 @@ fn impl_wf_environment<'i, I: Interner>( /// ``` fn compute_assoc_ty_goal( db: &dyn RustIrDatabase, - assoc_ty_id: AssociatedTyValueId, + assoc_term_id: AssociatedTermValueId, ) -> Option> { let mut gb = GoalBuilder::new(db); - let assoc_ty = &db.associated_ty_value(assoc_ty_id); + let assoc = &db.associated_term_value(assoc_term_id); // Create `forall { .. }` Some(gb.forall( - &assoc_ty.value.map_ref(|v| &v.ty), - assoc_ty_id, + &assoc.value.map_ref(|v| match v { + AssociatedTermValueBound::Ty(ty) => ty, + AssociatedTermValueBound::Const(ct) => todo!(), + }), + assoc_term_id, |gb, assoc_ty_substitution, value_ty, assoc_ty_id| { let interner = gb.interner(); let db = gb.db(); - // Hmm, because `Arc` does not implement `Fold`, we can't pass this value through, + // Hmm, because `Arc` does not implement `Fold`, we can't pass this value through, // just the id, so we have to fetch `assoc_ty` from the database again. - // Implementing `Fold` for `AssociatedTyValue` doesn't *quite* seem right though, as that + // Implementing `Fold` for `AssociatedTermValue` doesn't *quite* seem right though, as that // would result in a deep clone, and the value is inert. We could do some more refatoring // (move the `Arc` behind a newtype, for example) to fix this, but for now doesn't // seem worth it. - let assoc_ty = &db.associated_ty_value(assoc_ty_id); + let assoc_ty = &db.associated_term_value(assoc_ty_id); let (impl_parameters, projection) = db .impl_parameters_and_projection_from_associated_ty_value( @@ -615,8 +614,8 @@ fn compute_assoc_ty_goal( // * where clauses // * original in trait, `Self: 'a` // * after substituting impl parameters, `Box: '!a` - let assoc_ty_datum = db.associated_ty_data(projection.associated_term_id); - let AssociatedTyDatumBound { + let assoc_ty_datum = db.associated_term_data(projection.associated_term_id); + let AssociatedTermDatumBound { bounds: defn_bounds, where_clauses: defn_where_clauses, } = assoc_ty_datum From 082fe948efcb29340c30665b5c7ced19776242f2 Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 3 Jun 2022 22:24:42 +0000 Subject: [PATCH 07/14] Replace AliasEq::Ty w/ AliasEq::Term --- .../src/lowering/program_lowerer.rs | 8 +++----- chalk-integration/src/program.rs | 7 +++---- chalk-ir/src/lib.rs | 10 +++++----- chalk-solve/src/clauses.rs | 8 ++++---- chalk-solve/src/clauses/builder.rs | 4 ++-- .../builtin_traits/discriminant_kind.rs | 3 +-- .../src/clauses/builtin_traits/fn_family.rs | 3 +-- .../src/clauses/builtin_traits/generator.rs | 2 +- chalk-solve/src/clauses/program_clauses.rs | 12 ++++++------ chalk-solve/src/display.rs | 6 +++--- chalk-solve/src/display/bounds.rs | 4 ++-- chalk-solve/src/display/items.rs | 14 ++++++-------- chalk-solve/src/display/ty.rs | 9 +++++++++ chalk-solve/src/infer/unify.rs | 18 +++++++++++------- chalk-solve/src/logging_db/id_collector.rs | 4 +++- chalk-solve/src/rust_ir.rs | 9 +++++---- chalk-solve/src/wf.rs | 4 ++-- 17 files changed, 67 insertions(+), 58 deletions(-) diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index 1a8bedd62c5..2f2bd474915 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -5,8 +5,8 @@ use chalk_ir::{ }; use chalk_parse::ast::*; use chalk_solve::rust_ir::{ - self, Anonymize, GeneratorDatum, GeneratorInputOutputDatum, - GeneratorWitnessDatum, GeneratorWitnessExistential, OpaqueTyDatum, OpaqueTyDatumBound, + self, Anonymize, GeneratorDatum, GeneratorInputOutputDatum, GeneratorWitnessDatum, + GeneratorWitnessExistential, OpaqueTyDatum, OpaqueTyDatumBound, }; use rust_ir::IntoWhereClauses; use std::collections::{BTreeMap, HashSet}; @@ -340,9 +340,7 @@ impl ProgramLowerer { variable_kinds.extend(impl_defn.all_parameters()); let value = empty_env.in_binders(variable_kinds, |env| { - Ok(rust_ir::AssociatedTermValueBound::Ty( - atv.value.lower(env)?, - )) + Ok(rust_ir::AssociatedTermValueBound::Ty(atv.value.lower(env)?)) })?; associated_term_values.insert( diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 9765dd73ada..49ed1eb4859 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -9,10 +9,9 @@ use chalk_ir::{ Substitution, TraitId, Ty, TyKind, UintTy, Variances, }; use chalk_solve::rust_ir::{ - AdtDatum, AdtRepr, AdtSizeAlign, - AssociatedTermDatum, AssociatedTermValue, AssociatedTermValueId, ClosureKind, - FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, GeneratorWitnessDatum, ImplDatum, - ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait, + AdtDatum, AdtRepr, AdtSizeAlign, AssociatedTermDatum, AssociatedTermValue, + AssociatedTermValueId, ClosureKind, FnDefDatum, FnDefInputsAndOutputDatum, GeneratorDatum, + GeneratorWitnessDatum, ImplDatum, ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait, }; use chalk_solve::split::Split; use chalk_solve::RustIrDatabase; diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index f121d48fea2..6fd1259414a 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -743,11 +743,11 @@ impl TyKind { WhereClause::AliasEq(alias_eq) => { dyn_flags |= alias_eq.alias.compute_flags(interner); dyn_flags |= match &alias_eq.term { - Term::Ty(ty) => ty.data(interner).flags, - Term::Const(ct) => { - let const_data = ct.data(interner); - const_data.ty.data(interner).flags - }, + Term::Ty(ty) => ty.data(interner).flags, + Term::Const(ct) => { + let const_data = ct.data(interner); + const_data.ty.data(interner).flags + } }; } WhereClause::LifetimeOutlives(lifetime_outlives) => { diff --git a/chalk-solve/src/clauses.rs b/chalk-solve/src/clauses.rs index bb781bae588..c5612b7603a 100644 --- a/chalk-solve/src/clauses.rs +++ b/chalk-solve/src/clauses.rs @@ -787,7 +787,7 @@ fn push_alias_implemented_clause( DomainGoal::Holds(WhereClause::Implemented(fresh_self_trait_ref)), DomainGoal::Holds(WhereClause::AliasEq(AliasEq { alias: alias.clone(), - ty: bound_var, + term: Term::Ty(bound_var), })), ], ); @@ -825,12 +825,12 @@ fn push_alias_alias_eq_clause( ), ); let fresh_alias = AliasTy::Projection(ProjectionTerm { - associated_term_id: projection_ty.associated_term_id, + associated_term_id: projection_term.associated_term_id, substitution: fresh_self_subst, }); builder.push_clause( DomainGoal::Holds(WhereClause::AliasEq(AliasEq { - alias: AliasTy::Projection(projection_ty.clone()), + alias: AliasTy::Projection(projection_term.clone()), term: term.clone(), })), &[ @@ -840,7 +840,7 @@ fn push_alias_alias_eq_clause( })), DomainGoal::Holds(WhereClause::AliasEq(AliasEq { alias: alias.clone(), - term: bound_var, + term: Term::Ty(bound_var), })), ], ); diff --git a/chalk-solve/src/clauses/builder.rs b/chalk-solve/src/clauses/builder.rs index 48e0f7346eb..5969890dbbe 100644 --- a/chalk-solve/src/clauses/builder.rs +++ b/chalk-solve/src/clauses/builder.rs @@ -207,7 +207,7 @@ impl<'me, I: Interner> ClauseBuilder<'me, I> { /// passing a const representing this new const variable in as an /// argument. pub fn push_bound_const(&mut self, ty: Ty, op: impl FnOnce(&mut Self, Const)) { - let interner = self.interner(); + let interner = self.interner(); let binders = Binders::new( VariableKinds::from1(interner, VariableKind::Const(ty)), PhantomData::, @@ -219,7 +219,7 @@ impl<'me, I: Interner> ClauseBuilder<'me, I> { .unwrap() .assert_const_ref(interner) .clone(); - op(this, lifetime) + op(this, ct) }); } diff --git a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs index 8fb97c3202d..df5dc4de519 100644 --- a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs +++ b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs @@ -1,8 +1,7 @@ use crate::clauses::ClauseBuilder; use crate::{Interner, RustIrDatabase, TraitRef, WellKnownTrait}; use chalk_ir::{ - AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Ty, TyKind, TyVariableKind, - Term, + AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Term, Ty, TyKind, TyVariableKind, }; pub fn add_discriminant_clauses( diff --git a/chalk-solve/src/clauses/builtin_traits/fn_family.rs b/chalk-solve/src/clauses/builtin_traits/fn_family.rs index cd261526ab0..23043e29945 100644 --- a/chalk-solve/src/clauses/builtin_traits/fn_family.rs +++ b/chalk-solve/src/clauses/builtin_traits/fn_family.rs @@ -3,8 +3,7 @@ use crate::rust_ir::{ClosureKind, FnDefInputsAndOutputDatum, WellKnownTrait}; use crate::{Interner, RustIrDatabase, TraitRef}; use chalk_ir::cast::Cast; use chalk_ir::{ - AliasTy, Binders, Normalize, ProjectionTerm, Safety, Substitution, TraitId, Ty, TyKind, - Term, + AliasTy, Binders, Normalize, ProjectionTerm, Safety, Substitution, Term, TraitId, Ty, TyKind, }; fn push_clauses( diff --git a/chalk-solve/src/clauses/builtin_traits/generator.rs b/chalk-solve/src/clauses/builtin_traits/generator.rs index 80ab7c59677..6506199d381 100644 --- a/chalk-solve/src/clauses/builtin_traits/generator.rs +++ b/chalk-solve/src/clauses/builtin_traits/generator.rs @@ -2,7 +2,7 @@ use crate::clauses::ClauseBuilder; use crate::rust_ir::WellKnownTrait; use crate::{Interner, RustIrDatabase, TraitRef}; use chalk_ir::cast::Cast; -use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Ty, TyKind, Term}; +use chalk_ir::{AliasTy, Floundered, Normalize, ProjectionTerm, Substitution, Term, Ty, TyKind}; /// Add implicit impls of the generator trait, i.e., add a clause that all generators implement /// `Generator` and clauses for `Generator`'s associated types. diff --git a/chalk-solve/src/clauses/program_clauses.rs b/chalk-solve/src/clauses/program_clauses.rs index a6f2b837409..2c455fcffe0 100644 --- a/chalk-solve/src/clauses/program_clauses.rs +++ b/chalk-solve/src/clauses/program_clauses.rs @@ -127,8 +127,8 @@ impl ToProgramClauses for AssociatedTermValue { Normalize { alias: AliasTy::Projection(projection.clone()), term: match assoc_ty_value { - AssociatedTermValueBound::Ty(ty) => Term::Ty(ty), - AssociatedTermValueBound::Const(ct) => Term::Const(ct), + AssociatedTermValueBound::Ty(ty) => Term::Ty(ty), + AssociatedTermValueBound::Const(ct) => Term::Const(ct), }, }, impl_where_clauses.chain(assoc_ty_where_clauses), @@ -170,7 +170,7 @@ impl ToProgramClauses for OpaqueTyDatum { DomainGoal::Holds( AliasEq { alias: alias.clone(), - ty: builder.db.hidden_opaque_type(self.opaque_ty_id), + term: Term::Ty(builder.db.hidden_opaque_type(self.opaque_ty_id)), } .cast(interner), ), @@ -181,7 +181,7 @@ impl ToProgramClauses for OpaqueTyDatum { builder.push_fact(DomainGoal::Holds( AliasEq { alias, - ty: alias_placeholder_ty.clone(), + term: Term::Ty(alias_placeholder_ty.clone()), } .cast(interner), )); @@ -825,7 +825,7 @@ impl ToProgramClauses for AssociatedTermDatum { let projection_eq = AliasEq { alias: AliasTy::Projection(projection.clone()), - ty: ty.clone(), + term: Term::Ty(ty.clone()), }; // Fallback rule. The solver uses this to move between the projection @@ -907,7 +907,7 @@ impl ToProgramClauses for AssociatedTermDatum { // `AliasEq(::Assoc = U)` let projection_eq = AliasEq { alias: AliasTy::Projection(projection), - ty, + term: Term::Ty(ty), }; // Projection equality rule from above. diff --git a/chalk-solve/src/display.rs b/chalk-solve/src/display.rs index d6e81d0c69e..a5c62d8d4da 100644 --- a/chalk-solve/src/display.rs +++ b/chalk-solve/src/display.rs @@ -159,7 +159,7 @@ fn display_self_where_clauses_as_bounds<'a, I: Interner>( assoc_ty_datum, &trait_params[1..], assoc_type_params, - &alias_eq.ty, + &alias_eq.term, ) .fmt(f) } @@ -201,7 +201,7 @@ fn display_trait_with_assoc_ty_value<'a, I: Interner>( assoc_ty_datum: Arc>, trait_params: &'a [GenericArg], assoc_ty_params: &'a [GenericArg], - assoc_ty_value: &'a Ty, + assoc_term_value: &'a Term, ) -> impl Display + 'a { as_display(move |f| { write!(f, "{}<", assoc_ty_datum.trait_id.display(s))?; @@ -218,7 +218,7 @@ fn display_trait_with_assoc_ty_value<'a, I: Interner>( assoc_ty_params.iter().map(|param| param.display(s)), ", " )?; - write!(f, "={}>", assoc_ty_value.display(s))?; + write!(f, "={}>", assoc_term_value.display(s))?; Ok(()) }) } diff --git a/chalk-solve/src/display/bounds.rs b/chalk-solve/src/display/bounds.rs index e33b7366f14..fe684c7c192 100644 --- a/chalk-solve/src/display/bounds.rs +++ b/chalk-solve/src/display/bounds.rs @@ -37,7 +37,7 @@ impl RenderAsRust for AliasEqBound { s.db().associated_term_data(self.associated_ty_id), &self.trait_bound.args_no_self, &self.parameters, - &self.value, + &Term::Ty(self.value.clone()), ) .fmt(f) } @@ -144,7 +144,7 @@ impl RenderAsRust for AliasEq { assoc_ty_datum, &trait_params[1..], assoc_type_params, - &self.ty + &self.term, ), ) } diff --git a/chalk-solve/src/display/items.rs b/chalk-solve/src/display/items.rs index 5cee89d89cd..89aa62d4a20 100644 --- a/chalk-solve/src/display/items.rs +++ b/chalk-solve/src/display/items.rs @@ -299,12 +299,10 @@ impl RenderAsRust for ImplDatum { write!(f, "{{")?; { let s = &s.add_indent(); - let assoc_ty_values = self.associated_term_value_ids.iter().map(|av| { - s.db() - .associated_term_value(*av) - .display(s) - .to_string() - }); + let assoc_ty_values = self + .associated_term_value_ids + .iter() + .map(|av| s.db().associated_term_value(*av).display(s).to_string()); write_joined_non_empty_list!(f, "\n{}\n", assoc_ty_values, "\n")?; } write!(f, "}}")?; @@ -445,8 +443,8 @@ impl RenderAsRust for AssociatedTermValue { write!(f, "{}type {}", s.indent(), assoc_ty_data.id.display(s))?; write_joined_non_empty_list!(f, "<{}>", assoc_ty_value_display, ", ")?; match value { - AssociatedTermValueBound::Ty(ty) => write!(f, " = {};", ty.display(s))?, - AssociatedTermValueBound::Const(ct) => write!(f, " = const {};", ct.display(s))?, + AssociatedTermValueBound::Ty(ty) => write!(f, " = {};", ty.display(s))?, + AssociatedTermValueBound::Const(ct) => write!(f, " = const {};", ct.display(s))?, } Ok(()) } diff --git a/chalk-solve/src/display/ty.rs b/chalk-solve/src/display/ty.rs index 87a6efff88d..b97bd430c60 100644 --- a/chalk-solve/src/display/ty.rs +++ b/chalk-solve/src/display/ty.rs @@ -296,6 +296,15 @@ impl RenderAsRust for Const { } } +impl RenderAsRust for Term { + fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { + match self { + Term::Ty(ty) => ty.fmt(s, f), + Term::Const(ct) => ct.fmt(s, f), + } + } +} + impl RenderAsRust for GenericArg { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { // delegate to GenericArgData diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index 9c1782ea5ce..2528f0e2655 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -465,14 +465,15 @@ impl<'t, I: Interner> Unifier<'t, I> { self.environment, AliasEq { alias: alias.clone(), - ty: ty.clone(), + term: Term::Ty(ty.clone()), } .cast(interner), )); Ok(()) } Variance::Covariant | Variance::Contravariant => { - let var = self + // TODO need to convert this into type or const. + let term = self .table .new_variable(UniverseIndex::root()) .to_ty(interner); @@ -480,11 +481,12 @@ impl<'t, I: Interner> Unifier<'t, I> { self.environment, AliasEq { alias: alias.clone(), - ty: var.clone(), + term: Term::Ty(term.clone()), } .cast(interner), )); - self.relate_ty_ty(variance, &var, ty) + // TODO this should vary whether it relates a type or a const + self.relate_ty_ty(variance, &term, ty) } } } @@ -629,7 +631,7 @@ impl<'t, I: Interner> Unifier<'t, I> { }) } WhereClause::AliasEq(alias_eq) => { - let AliasEq { alias, ty: _ } = alias_eq; + let AliasEq { alias, term: _ } = alias_eq; let alias = match alias { AliasTy::Opaque(opaque_ty) => { let OpaqueTy { @@ -668,9 +670,11 @@ impl<'t, I: Interner> Unifier<'t, I> { }) } }; - let ty = + // TODO need to convert this to a type or a const. + let term = self.table.new_variable(universe_index).to_ty(interner); - WhereClause::AliasEq(AliasEq { alias, ty }) + let term = Term::Ty(term); + WhereClause::AliasEq(AliasEq { alias, term }) } WhereClause::TypeOutlives(_) => { let lifetime_var = self.table.new_variable(universe_index); diff --git a/chalk-solve/src/logging_db/id_collector.rs b/chalk-solve/src/logging_db/id_collector.rs index 5992b62d0d8..1f412de545e 100644 --- a/chalk-solve/src/logging_db/id_collector.rs +++ b/chalk-solve/src/logging_db/id_collector.rs @@ -108,7 +108,9 @@ impl<'i, I: Interner, DB: RustIrDatabase> IdCollector<'i, I, DB> { fn visit_alias(&mut self, alias: &AliasTy) { match alias { AliasTy::Projection(projection_ty) => { - let assoc_ty_datum = self.db.associated_term_data(projection_ty.associated_term_id); + let assoc_ty_datum = self + .db + .associated_term_data(projection_ty.associated_term_id); self.record(assoc_ty_datum.trait_id) } AliasTy::Opaque(opaque_ty) => self.record(opaque_ty.opaque_ty_id), diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index b570135f1a8..d2629234414 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -7,9 +7,9 @@ use chalk_ir::cast::Cast; use chalk_ir::fold::shift::Shift; use chalk_ir::interner::Interner; use chalk_ir::{ - try_break, visit::Visit, AdtId, AliasEq, AliasTy, AssocItemId, Binders, DebruijnIndex, FnDefId, - GenericArg, ImplId, OpaqueTyId, ProjectionTerm, QuantifiedWhereClause, Substitution, - ToGenericArg, TraitId, TraitRef, Ty, TyKind, Const, VariableKind, WhereClause, WithKind, + try_break, visit::Visit, AdtId, AliasEq, AliasTy, AssocItemId, Binders, Const, DebruijnIndex, + FnDefId, GenericArg, ImplId, OpaqueTyId, ProjectionTerm, QuantifiedWhereClause, Substitution, + Term, ToGenericArg, TraitId, TraitRef, Ty, TyKind, VariableKind, WhereClause, WithKind, }; use std::iter; use std::ops::ControlFlow; @@ -448,7 +448,8 @@ impl AliasEqBound { associated_term_id: self.associated_ty_id, substitution, }), - ty: self.value.clone(), + // TODO here self.value should be a Term already. + term: Term::Ty(self.value.clone()), }), ] } diff --git a/chalk-solve/src/wf.rs b/chalk-solve/src/wf.rs index 9aed23e76ba..ebcde216e81 100644 --- a/chalk-solve/src/wf.rs +++ b/chalk-solve/src/wf.rs @@ -566,8 +566,8 @@ fn compute_assoc_ty_goal( // Create `forall { .. }` Some(gb.forall( &assoc.value.map_ref(|v| match v { - AssociatedTermValueBound::Ty(ty) => ty, - AssociatedTermValueBound::Const(ct) => todo!(), + AssociatedTermValueBound::Ty(ty) => ty, + AssociatedTermValueBound::Const(_ct) => todo!(), }), assoc_term_id, |gb, assoc_ty_substitution, value_ty, assoc_ty_id| { From eedf4c2b6dcc58e360abf6732511c15767b6b1d9 Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 3 Jun 2022 22:43:47 +0000 Subject: [PATCH 08/14] Fix tests --- tests/display/unique_names.rs | 14 +++++++------- tests/integration/panic.rs | 11 +++++------ tests/lowering/mod.rs | 29 ++++++++++++++++++++++++++++- tests/test/type_flags.rs | 4 ++-- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/tests/display/unique_names.rs b/tests/display/unique_names.rs index 6c1358a9594..71642e72a07 100644 --- a/tests/display/unique_names.rs +++ b/tests/display/unique_names.rs @@ -58,11 +58,11 @@ where fn custom_clauses(&self) -> Vec> { self.db.custom_clauses() } - fn associated_ty_data( + fn associated_term_data( &self, ty: chalk_ir::AssocItemId, - ) -> std::sync::Arc> { - self.db.associated_ty_data(ty) + ) -> std::sync::Arc> { + self.db.associated_term_data(ty) } fn trait_datum( &self, @@ -94,11 +94,11 @@ where ) -> std::sync::Arc> { self.db.impl_datum(impl_id) } - fn associated_ty_value( + fn associated_term_value( &self, - id: chalk_solve::rust_ir::AssociatedTyValueId, - ) -> std::sync::Arc> { - self.db.associated_ty_value(id) + id: chalk_solve::rust_ir::AssociatedTermValueId, + ) -> std::sync::Arc> { + self.db.associated_term_value(id) } fn generator_datum( &self, diff --git a/tests/integration/panic.rs b/tests/integration/panic.rs index 9c6a23ca418..06725792bc5 100644 --- a/tests/integration/panic.rs +++ b/tests/integration/panic.rs @@ -54,7 +54,7 @@ impl RustIrDatabase for MockDatabase { vec![] } - fn associated_ty_data(&self, ty: AssocItemId) -> Arc> { + fn associated_term_data(&self, ty: AssocItemId) -> Arc> { unimplemented!() } @@ -114,15 +114,14 @@ impl RustIrDatabase for MockDatabase { polarity: Polarity::Positive, binders, impl_type: ImplType::Local, - associated_ty_value_ids: vec![], - associated_const_value_ids: vec![], + associated_term_value_ids: vec![], }) } - fn associated_ty_value( + fn associated_term_value( &self, - id: AssociatedTyValueId, - ) -> Arc> { + id: AssociatedTermValueId, + ) -> Arc> { unimplemented!() } diff --git a/tests/lowering/mod.rs b/tests/lowering/mod.rs index 0a74b297132..3b301ff4455 100644 --- a/tests/lowering/mod.rs +++ b/tests/lowering/mod.rs @@ -13,6 +13,33 @@ fn lower_success() { } } +#[test] +fn lower_assoc_term() { + lowering_success! { + program { + trait Bar { + const N: usize; + } + struct Foo; + impl Bar for Foo { + const N: usize = 100; + } + } + } + + lowering_success! { + program { + trait Bar { + type T; + } + struct Foo; + impl Bar for Foo { + type T = usize; + } + } + } +} + #[test] fn not_trait() { lowering_error! { @@ -184,7 +211,7 @@ fn atc_accounting() { db.with_program(|program| { let atv_text = format!( "{:#?}", - &program.associated_ty_values.values().next().unwrap() + &program.associated_term_values.values().next().unwrap() ); println!("{}", atv_text); assert_eq!( diff --git a/tests/test/type_flags.rs b/tests/test/type_flags.rs index 0575657f0df..b8a9ecab5bc 100644 --- a/tests/test/type_flags.rs +++ b/tests/test/type_flags.rs @@ -1,7 +1,7 @@ use chalk_integration::interner::ChalkIr; use chalk_integration::{empty_substitution, lifetime, ty}; use chalk_ir::cast::Cast; -use chalk_ir::{PlaceholderIndex, TyKind, TypeFlags, UniverseIndex}; +use chalk_ir::{PlaceholderIndex, Term, TyKind, TypeFlags, UniverseIndex}; #[test] fn placeholder_ty_flags_correct() { @@ -56,7 +56,7 @@ fn dyn_ty_flags_correct() { vec![chalk_ir::Binders::>::empty( ChalkIr, chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { - ty: internal_ty, + term: Term::Ty(internal_ty), alias: chalk_ir::AliasTy::Projection(projection_ty), }), )], From e85c516184970ca5585fb298f05bc1ae6f93a2d9 Mon Sep 17 00:00:00 2001 From: kadmin Date: Fri, 3 Jun 2022 23:07:22 +0000 Subject: [PATCH 09/14] Add const defns in trait defn --- .../src/lowering/program_lowerer.rs | 28 ++++++++++++++++++- tests/lowering/mod.rs | 4 ++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index 2f2bd474915..adc5529c644 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -71,6 +71,14 @@ impl ProgramLowerer { self.associated_term_lookups .insert((TraitId(raw_id), defn.name.str.clone()), lookup); } + for defn in &d.assoc_const_defns { + let lookup = AssociatedTermLookup { + id: AssocItemId(self.next_item_id()), + addl_variable_kinds: vec![], + }; + self.associated_term_lookups + .insert((TraitId(raw_id), defn.name.str.clone()), lookup); + } } Item::Impl(d) => { @@ -314,7 +322,25 @@ impl ProgramLowerer { ); } for assoc_ct_defn in &trait_defn.assoc_const_defns { - todo!(); + let lookup = &self.associated_term_lookups + [&(trait_id, assoc_ct_defn.name.str.clone())]; + // assoc const has no parameters + let binders = + empty_env.in_binders(trait_defn.all_parameters(), |_env| { + Ok(rust_ir::AssociatedTermDatumBound { + bounds: vec![], + where_clauses: vec![], + }) + })?; + associated_term_data.insert( + lookup.id, + Arc::new(rust_ir::AssociatedTermDatum { + trait_id: TraitId(raw_id), + id: lookup.id, + name: assoc_ct_defn.name.str.clone(), + binders, + }), + ); } } Item::Impl(ref impl_defn) => { diff --git a/tests/lowering/mod.rs b/tests/lowering/mod.rs index 3b301ff4455..5b4343a548f 100644 --- a/tests/lowering/mod.rs +++ b/tests/lowering/mod.rs @@ -20,13 +20,14 @@ fn lower_assoc_term() { trait Bar { const N: usize; } - struct Foo; + struct Foo {} impl Bar for Foo { const N: usize = 100; } } } + /* lowering_success! { program { trait Bar { @@ -38,6 +39,7 @@ fn lower_assoc_term() { } } } + */ } #[test] From 75e5e25f3a81f8d5cd443254d88ef0697eb3c8f4 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 4 Jun 2022 01:44:38 +0000 Subject: [PATCH 10/14] Complete assoc const lowering --- chalk-integration/src/lowering.rs | 2 +- .../src/lowering/program_lowerer.rs | 28 ++++++++++++++++++- chalk-solve/src/wf.rs | 16 +++++++---- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index f768a09ebef..4eac2d2d06b 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -48,7 +48,7 @@ impl Lower for Program { .map(|_| lowerer.next_item_id()) .collect::>(); - lowerer.extract_associated_types(self, &raw_ids)?; + lowerer.extract_associated_terms(self, &raw_ids)?; lowerer.extract_ids(self, &raw_ids)?; lowerer.lower(self, &raw_ids) } diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index adc5529c644..116faddc7c6 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -51,7 +51,7 @@ impl ProgramLowerer { } /// Create ids for associated type declarations and values - pub fn extract_associated_types( + pub fn extract_associated_terms( &mut self, program: &Program, raw_ids: &[RawId], @@ -87,6 +87,11 @@ impl ProgramLowerer { self.associated_term_value_ids .insert((ImplId(raw_id), atv.name.str.clone()), atv_id); } + for atv in &d.assoc_const_values { + let atv_id = rust_ir::AssociatedTermValueId(self.next_item_id()); + self.associated_term_value_ids + .insert((ImplId(raw_id), atv.name.str.clone()), atv_id); + } } _ => {} @@ -378,6 +383,27 @@ impl ProgramLowerer { }), ); } + + for acv in &impl_defn.assoc_const_values { + let acv_id = + self.associated_term_value_ids[&(impl_id, acv.name.str.clone())]; + let lookup = + &self.associated_term_lookups[&(trait_id, acv.name.str.clone())]; + + let value = empty_env.in_binders(vec![], |env| { + Ok(rust_ir::AssociatedTermValueBound::Const( + acv.value.lower(env)?, + )) + })?; + associated_term_values.insert( + acv_id, + Arc::new(rust_ir::AssociatedTermValue { + impl_id, + associated_term_id: lookup.id, + value, + }), + ); + } } Item::Clause(ref clause) => { custom_clauses.extend(clause.lower(&empty_env)?); diff --git a/chalk-solve/src/wf.rs b/chalk-solve/src/wf.rs index ebcde216e81..e3f5b210a86 100644 --- a/chalk-solve/src/wf.rs +++ b/chalk-solve/src/wf.rs @@ -566,11 +566,11 @@ fn compute_assoc_ty_goal( // Create `forall { .. }` Some(gb.forall( &assoc.value.map_ref(|v| match v { - AssociatedTermValueBound::Ty(ty) => ty, - AssociatedTermValueBound::Const(_ct) => todo!(), + AssociatedTermValueBound::Ty(ty) => Term::Ty(ty.clone()), + AssociatedTermValueBound::Const(ct) => Term::Const(ct.clone()), }), assoc_term_id, - |gb, assoc_ty_substitution, value_ty, assoc_ty_id| { + |gb, assoc_ty_substitution, value_term, assoc_ty_id| { let interner = gb.interner(); let db = gb.db(); @@ -630,7 +630,7 @@ fn compute_assoc_ty_goal( .cloned() .map(|qwc| qwc.into_from_env_goal(interner)), |gb| { - let types = InputTypeCollector::types_in(gb.interner(), value_ty); + let types = InputTypeCollector::types_in(gb.interner(), value_term); // We require that `WellFormed(T)` for each type that appears in the value let wf_goals = types @@ -645,10 +645,16 @@ fn compute_assoc_ty_goal( // In our example, the bound was `Clone`, so the combined // result is `Box: Clone`. This is then converted to a // well-formed goal like `WellFormed(Box: Clone)`. + // + // In the case that the value_term is a const, we don't need to do + // anything extra, since all we have to check there is equality. let bound_goals = defn_bounds .iter() .cloned() - .flat_map(|qb| qb.into_where_clauses(interner, (*value_ty).clone())) + .flat_map(|qb| match value_term { + Term::Ty(ty) => qb.into_where_clauses(interner, (*ty).clone()), + Term::Const(_ct) => vec![], + }) .map(|qwc| qwc.into_well_formed_goal(interner)) .casted(interner); From 01c5c73bb161e115755e31199935ccc04bdc33c0 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 4 Jun 2022 02:03:37 +0000 Subject: [PATCH 11/14] Fix accounting test --- chalk-solve/src/display.rs | 5 ++++- chalk-solve/src/display/ty.rs | 2 ++ tests/lowering/mod.rs | 16 +++++++--------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/chalk-solve/src/display.rs b/chalk-solve/src/display.rs index a5c62d8d4da..6f46e811b68 100644 --- a/chalk-solve/src/display.rs +++ b/chalk-solve/src/display.rs @@ -218,7 +218,10 @@ fn display_trait_with_assoc_ty_value<'a, I: Interner>( assoc_ty_params.iter().map(|param| param.display(s)), ", " )?; - write!(f, "={}>", assoc_term_value.display(s))?; + match assoc_term_value { + Term::Ty(t) => write!(f, "={}>", t.display(s))?, + Term::Const(ct) => write!(f, "={}>", ct.display(s))?, + } Ok(()) }) } diff --git a/chalk-solve/src/display/ty.rs b/chalk-solve/src/display/ty.rs index b97bd430c60..cc28e1dac87 100644 --- a/chalk-solve/src/display/ty.rs +++ b/chalk-solve/src/display/ty.rs @@ -296,6 +296,7 @@ impl RenderAsRust for Const { } } +/* impl RenderAsRust for Term { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &mut Formatter<'_>) -> Result { match self { @@ -304,6 +305,7 @@ impl RenderAsRust for Term { } } } +*/ impl RenderAsRust for GenericArg { fn fmt(&self, s: &InternalWriterState<'_, I>, f: &'_ mut Formatter<'_>) -> Result { diff --git a/tests/lowering/mod.rs b/tests/lowering/mod.rs index 5b4343a548f..1273c157a04 100644 --- a/tests/lowering/mod.rs +++ b/tests/lowering/mod.rs @@ -27,19 +27,17 @@ fn lower_assoc_term() { } } - /* lowering_success! { program { trait Bar { type T; } - struct Foo; + struct Foo {} impl Bar for Foo { type T = usize; } } } - */ } #[test] @@ -218,12 +216,12 @@ fn atc_accounting() { println!("{}", atv_text); assert_eq!( &atv_text[..].replace(",\n", "\n"), - &r#"AssociatedTyValue { + &r#"AssociatedTermValue { impl_id: ImplId(#2), - associated_ty_id: (Iterable::Iter), - value: for AssociatedTyValueBound { - ty: Iter<'^0.0, ^0.1> - }, + associated_term_id: (Iterable::Iter), + value: for Ty( + Iter<'^0.0, ^0.1> + ), }"# .replace(",\n", "\n"), ); @@ -240,7 +238,7 @@ fn atc_accounting() { "ForAll { \ ForAll { \ ForAll { \ - all(AliasEq(<^2.0 as Iterable>::Iter<'^1.0> = ^0.0), \ + all(AliasEq(<^2.0 as Iterable>::Iter<'^1.0> = Ty(^0.0)), \ Implemented(^2.0: Iterable)) \ } \ } \ From bdb4336a326433d306977322d4bcfccfb7211693 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 4 Jun 2022 02:34:38 +0000 Subject: [PATCH 12/14] Fix test compilation --- chalk-solve/src/display.rs | 4 ++-- tests/test/projection.rs | 17 +++++------------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/chalk-solve/src/display.rs b/chalk-solve/src/display.rs index 6f46e811b68..00334ba6b88 100644 --- a/chalk-solve/src/display.rs +++ b/chalk-solve/src/display.rs @@ -219,8 +219,8 @@ fn display_trait_with_assoc_ty_value<'a, I: Interner>( ", " )?; match assoc_term_value { - Term::Ty(t) => write!(f, "={}>", t.display(s))?, - Term::Const(ct) => write!(f, "={}>", ct.display(s))?, + Term::Ty(t) => write!(f, "={}>", t.display(s))?, + Term::Const(ct) => write!(f, "={}>", ct.display(s))?, } Ok(()) }) diff --git a/tests/test/projection.rs b/tests/test/projection.rs index 26f5e0bfec8..7b0e343c6db 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -1112,22 +1112,15 @@ fn projection_to_opaque() { fn const_projection() { test! { program { - trait ConstTrait { - const ID: usize; - } - trait OtherTrait {} - impl OtherTrait for U where U: ConstTrait {} - impl ConstTrait for () { - const ID: usize = 3; - } - impl ConstTrait for i32 { - const ID: usize = 5; - } + trait ConstTrait { const N: usize; } + impl ConstTrait for () { const N: usize = 3; } + impl ConstTrait for i32 { const N: usize = 5; } } goal { + ::N = 3 } yields { - expect![["Unique"]] + expect![[]] } } } From 0314a1f757c6949e3a244b1a7cc818f6a36592b2 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 4 Jun 2022 05:20:04 +0000 Subject: [PATCH 13/14] Add temporary incorrect value --- tests/test/projection.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test/projection.rs b/tests/test/projection.rs index 7b0e343c6db..a80fe1b588c 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -1120,7 +1120,7 @@ fn const_projection() { goal { ::N = 3 } yields { - expect![[]] + expect![[r#"No possible solution"#]] } } } From cedba56f0a6f6599ea996332901021e9d07cc799 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sat, 4 Jun 2022 09:05:34 +0000 Subject: [PATCH 14/14] Add associated term values --- chalk-integration/src/lowering.rs | 27 +++++--- chalk-integration/src/lowering/env.rs | 2 +- .../src/lowering/program_lowerer.rs | 17 ++--- .../builtin_traits/discriminant_kind.rs | 2 +- .../src/clauses/builtin_traits/fn_family.rs | 6 +- .../src/clauses/builtin_traits/generator.rs | 8 +-- chalk-solve/src/clauses/env_elaborator.rs | 2 +- chalk-solve/src/clauses/program_clauses.rs | 50 +++++++++----- chalk-solve/src/display/items.rs | 6 +- chalk-solve/src/display/stub.rs | 5 +- chalk-solve/src/infer/unify.rs | 66 ++++++++++++------- chalk-solve/src/logging_db/id_collector.rs | 8 +-- chalk-solve/src/rust_ir.rs | 6 +- chalk-solve/src/wf.rs | 1 + tests/integration/panic.rs | 2 +- tests/test/projection.rs | 4 +- 16 files changed, 134 insertions(+), 78 deletions(-) diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index 4eac2d2d06b..05f25e6ce8a 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -495,7 +495,7 @@ impl LowerWithEnv for AliasEqBound { fn lower(&self, env: &Env) -> LowerResult { let trait_bound = self.trait_bound.lower(env)?; - let lookup = env.lookup_associated_ty(trait_bound.trait_id, &self.name)?; + let lookup = env.lookup_associated_term(trait_bound.trait_id, &self.name)?; let args: Vec<_> = self .args .iter() @@ -632,7 +632,7 @@ impl LowerWithEnv for ProjectionTerm { trait_id, substitution: trait_substitution, } = trait_ref.lower(env)?; - let lookup = env.lookup_associated_ty(trait_id, name)?; + let lookup = env.lookup_associated_term(trait_id, name)?; let mut args: Vec<_> = args .iter() .map(|a| a.lower(env)) @@ -928,13 +928,14 @@ impl LowerWithEnv for (&Impl, ImplId, &AssociatedTermValueIds) { }) })?; - // lookup the ids for each of the "associated type values" + // lookup the ids for each of the "associated term values" // within the impl, which should have already assigned and // stored in the map let assoc_const_values = impl_ .assoc_const_values .iter() .map(|av| associated_term_value_ids[&(*impl_id, av.name.str.clone())]); + let associated_term_value_ids = impl_ .assoc_ty_values .iter() @@ -1016,17 +1017,25 @@ impl LowerWithEnv for (&TraitDefn, chalk_ir::TraitId) { }) })?; - let associated_ty_ids: Vec<_> = trait_defn - .assoc_ty_defns - .iter() - .map(|defn| env.lookup_associated_ty(*trait_id, &defn.name).unwrap().id) - .collect(); + let assoc_ct_ids = trait_defn.assoc_const_defns.iter().map(|defn| { + env.lookup_associated_term(*trait_id, &defn.name) + .unwrap() + .id + }); + + let assoc_ty_ids = trait_defn.assoc_ty_defns.iter().map(|defn| { + env.lookup_associated_term(*trait_id, &defn.name) + .unwrap() + .id + }); + + let associated_term_ids: Vec<_> = assoc_ty_ids.chain(assoc_ct_ids).collect(); let trait_datum = rust_ir::TraitDatum { id: *trait_id, binders, flags: trait_defn.flags.lower(), - associated_ty_ids, + associated_term_ids, well_known: trait_defn.well_known.map(|def| def.lower()), }; diff --git a/chalk-integration/src/lowering/env.rs b/chalk-integration/src/lowering/env.rs index dd95668e84e..d498e700749 100644 --- a/chalk-integration/src/lowering/env.rs +++ b/chalk-integration/src/lowering/env.rs @@ -214,7 +214,7 @@ impl Env<'_> { &self.generator_kinds[&id] } - pub fn lookup_associated_ty( + pub fn lookup_associated_term( &self, trait_id: TraitId, ident: &Identifier, diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index 116faddc7c6..f4f8104760a 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -313,6 +313,7 @@ impl ProgramLowerer { Ok(rust_ir::AssociatedTermDatumBound { bounds: assoc_ty_defn.bounds.lower(env)?, where_clauses: assoc_ty_defn.where_clauses.lower(env)?, + assoc_const_ty: None, }) })?; @@ -326,17 +327,17 @@ impl ProgramLowerer { }), ); } + for assoc_ct_defn in &trait_defn.assoc_const_defns { let lookup = &self.associated_term_lookups [&(trait_id, assoc_ct_defn.name.str.clone())]; - // assoc const has no parameters - let binders = - empty_env.in_binders(trait_defn.all_parameters(), |_env| { - Ok(rust_ir::AssociatedTermDatumBound { - bounds: vec![], - where_clauses: vec![], - }) - })?; + let binders = empty_env.in_binders(trait_defn.all_parameters(), |env| { + Ok(rust_ir::AssociatedTermDatumBound { + bounds: vec![], + where_clauses: vec![], + assoc_const_ty: Some(assoc_ct_defn.ty.lower(env)?), + }) + })?; associated_term_data.insert( lookup.id, Arc::new(rust_ir::AssociatedTermDatum { diff --git a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs index df5dc4de519..62ab24cf7b4 100644 --- a/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs +++ b/chalk-solve/src/clauses/builtin_traits/discriminant_kind.rs @@ -50,7 +50,7 @@ pub fn add_discriminant_clauses( .unwrap(); let trait_datum = db.trait_datum(trait_id); - let associated_ty_id = trait_datum.associated_ty_ids[0]; + let associated_ty_id = trait_datum.associated_term_ids[0]; let substitution = Substitution::from1(interner, self_ty); let trait_ref = TraitRef { diff --git a/chalk-solve/src/clauses/builtin_traits/fn_family.rs b/chalk-solve/src/clauses/builtin_traits/fn_family.rs index 23043e29945..768703dbf41 100644 --- a/chalk-solve/src/clauses/builtin_traits/fn_family.rs +++ b/chalk-solve/src/clauses/builtin_traits/fn_family.rs @@ -28,14 +28,14 @@ fn push_clauses( if let WellKnownTrait::FnOnce = well_known { let trait_datum = db.trait_datum(trait_id); assert_eq!( - trait_datum.associated_ty_ids.len(), + trait_datum.associated_term_ids.len(), 1, "FnOnce trait should have exactly one associated type, found {:?}", - trait_datum.associated_ty_ids + trait_datum.associated_term_ids ); // Constructs the alias. For `Fn`, for example, this would look like // `Normalize( B as FnOnce<(A,)>>::Output -> B)` - let output_id = trait_datum.associated_ty_ids[0]; + let output_id = trait_datum.associated_term_ids[0]; let alias = AliasTy::Projection(ProjectionTerm { associated_term_id: output_id, substitution, diff --git a/chalk-solve/src/clauses/builtin_traits/generator.rs b/chalk-solve/src/clauses/builtin_traits/generator.rs index 6506199d381..141a31c10ee 100644 --- a/chalk-solve/src/clauses/builtin_traits/generator.rs +++ b/chalk-solve/src/clauses/builtin_traits/generator.rs @@ -24,10 +24,10 @@ pub fn add_generator_program_clauses( let trait_id = db.well_known_trait_id(WellKnownTrait::Generator).unwrap(); let trait_datum = db.trait_datum(trait_id); assert_eq!( - trait_datum.associated_ty_ids.len(), + trait_datum.associated_term_ids.len(), 2, "Generator trait should have exactly two associated types, found {:?}", - trait_datum.associated_ty_ids + trait_datum.associated_term_ids ); let substitution = Substitution::from_iter( @@ -45,7 +45,7 @@ pub fn add_generator_program_clauses( }); // `Generator::Yield` - let yield_id = trait_datum.associated_ty_ids[0]; + let yield_id = trait_datum.associated_term_ids[0]; let yield_alias = AliasTy::Projection(ProjectionTerm { associated_term_id: yield_id, substitution: substitution.clone(), @@ -56,7 +56,7 @@ pub fn add_generator_program_clauses( }); // `Generator::Return` - let return_id = trait_datum.associated_ty_ids[1]; + let return_id = trait_datum.associated_term_ids[1]; let return_alias = AliasTy::Projection(ProjectionTerm { associated_term_id: return_id, substitution, diff --git a/chalk-solve/src/clauses/env_elaborator.rs b/chalk-solve/src/clauses/env_elaborator.rs index 3d13605795c..d0009b5189e 100644 --- a/chalk-solve/src/clauses/env_elaborator.rs +++ b/chalk-solve/src/clauses/env_elaborator.rs @@ -91,7 +91,7 @@ impl<'me, 'builder, I: Interner> Visitor for EnvElaborator<'me, 'builder, I> // If we know that `T: Iterator`, then we also know // things about `::Item`, so push those // implied bounds too: - for &ai in &trait_datum.associated_ty_ids { + for &ai in &trait_datum.associated_term_ids { self.db .associated_term_data(ai) .to_program_clauses(self.builder, self.environment); diff --git a/chalk-solve/src/clauses/program_clauses.rs b/chalk-solve/src/clauses/program_clauses.rs index 2c455fcffe0..ae908ae781b 100644 --- a/chalk-solve/src/clauses/program_clauses.rs +++ b/chalk-solve/src/clauses/program_clauses.rs @@ -81,9 +81,9 @@ impl ToProgramClauses for AssociatedTermValue { _environment: &Environment, ) { let impl_datum = builder.db.impl_datum(self.impl_id); - let associated_ty = builder.db.associated_term_data(self.associated_term_id); + let associated_term = builder.db.associated_term_data(self.associated_term_id); - builder.push_binders(self.value.clone(), |builder, assoc_ty_value| { + builder.push_binders(self.value.clone(), |builder, assoc_term_value| { let all_parameters = builder.placeholders_in_scope().to_vec(); // Get the projection for this associated type: @@ -107,7 +107,7 @@ impl ToProgramClauses for AssociatedTermValue { // 2. any where-clauses from the `type` declaration in the trait: the // parameters must be substituted with those of the impl - let assoc_ty_where_clauses = associated_ty + let assoc_term_where_clauses = associated_term .binders .map_ref(|b| &b.where_clauses) .into_iter() @@ -123,16 +123,20 @@ impl ToProgramClauses for AssociatedTermValue { // Implemented(Iter<'a, T>: 'a). // (2) // } // ``` - builder.push_clause( - Normalize { - alias: AliasTy::Projection(projection.clone()), - term: match assoc_ty_value { - AssociatedTermValueBound::Ty(ty) => Term::Ty(ty), - AssociatedTermValueBound::Const(ct) => Term::Const(ct), - }, - }, - impl_where_clauses.chain(assoc_ty_where_clauses), - ); + match assoc_term_value { + AssociatedTermValueBound::Ty(ty) => { + builder.push_clause( + Normalize { + alias: AliasTy::Projection(projection.clone()), + term: Term::Ty(ty), + }, + impl_where_clauses.chain(assoc_term_where_clauses), + ); + } + AssociatedTermValueBound::Const(ct) => { + todo!(); + } + } }); } } @@ -801,12 +805,15 @@ impl ToProgramClauses for AssociatedTermDatum { ) { let interner = builder.interner(); let binders = self.binders.clone(); + // otherwise known to be a type. + builder.push_binders( binders, |builder, AssociatedTermDatumBound { where_clauses, bounds, + assoc_const_ty, }| { let substitution = builder.substitution_in_scope(); @@ -882,8 +889,8 @@ impl ToProgramClauses for AssociatedTermDatum { // forall { // FromEnv(::Assoc: Bounds) :- FromEnv(Self: Foo), WC // } - for quantified_bound in bounds { - builder.push_binders(quantified_bound, |builder, bound| { + for quantified_bound in bounds.iter() { + builder.push_binders(quantified_bound.clone(), |builder, bound| { for wc in bound.into_where_clauses(interner, projection_ty.clone()) { builder.push_clause( wc.into_from_env_goal(interner), @@ -906,7 +913,7 @@ impl ToProgramClauses for AssociatedTermDatum { // `AliasEq(::Assoc = U)` let projection_eq = AliasEq { - alias: AliasTy::Projection(projection), + alias: AliasTy::Projection(projection.clone()), term: Term::Ty(ty), }; @@ -918,6 +925,17 @@ impl ToProgramClauses for AssociatedTermDatum { // } builder.push_clause(projection_eq, Some(normalize)); }); + if let Some(act) = assoc_const_ty { + builder.push_bound_const(act, |builder, ct| { + // `AliasEq(::Assoc = U)` + let projection_eq = AliasEq { + alias: AliasTy::Projection(projection), + term: Term::Const(ct), + }; + builder.push_fact(projection_eq); + }); + // todo!() + } }, ); } diff --git a/chalk-solve/src/display/items.rs b/chalk-solve/src/display/items.rs index 89aa62d4a20..32f0419bcd4 100644 --- a/chalk-solve/src/display/items.rs +++ b/chalk-solve/src/display/items.rs @@ -228,9 +228,9 @@ impl RenderAsRust for TraitDatum { write_joined_non_empty_list!( f, "\n{}\n", - self.associated_ty_ids.iter().map(|assoc_id| { - let assoc_ty_data = s.db().associated_term_data(*assoc_id); - format!("{}{}", s.indent(), (*assoc_ty_data).display(s)) + self.associated_term_ids.iter().map(|assoc_id| { + let assoc_data = s.db().associated_term_data(*assoc_id); + format!("{}{}", s.indent(), (*assoc_data).display(s)) }), "\n" )?; diff --git a/chalk-solve/src/display/stub.rs b/chalk-solve/src/display/stub.rs index 94c83fb5ff8..c2af3241ac3 100644 --- a/chalk-solve/src/display/stub.rs +++ b/chalk-solve/src/display/stub.rs @@ -43,14 +43,15 @@ impl> RustIrDatabase for StubWrapper<'_, D fn associated_term_data( &self, - ty: chalk_ir::AssocItemId, + id: chalk_ir::AssocItemId, ) -> Arc> { - let mut v = (*self.db.associated_term_data(ty)).clone(); + let mut v = (*self.db.associated_term_data(id)).clone(); v.binders = Binders::new( v.binders.binders.clone(), AssociatedTermDatumBound { where_clauses: Vec::new(), bounds: Vec::new(), + assoc_const_ty: None, }, ); Arc::new(v) diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index 2528f0e2655..d11829905bc 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -181,8 +181,12 @@ impl<'t, I: Interner> Unifier<'t, I> { ), // Unifying an alias type with some other type `U`. - (_, &TyKind::Alias(ref alias)) => self.relate_alias_ty(variance.invert(), alias, a), - (&TyKind::Alias(ref alias), _) => self.relate_alias_ty(variance, alias, b), + (_, &TyKind::Alias(ref alias)) => { + self.relate_alias_term(variance.invert(), alias, &Term::Ty(a.clone())) + } + (&TyKind::Alias(ref alias), _) => { + self.relate_alias_term(variance, alias, &Term::Ty(b.clone())) + } (&TyKind::InferenceVar(var, kind), ty_data) => { let ty = ty_data.clone().intern(interner); @@ -452,11 +456,11 @@ impl<'t, I: Interner> Unifier<'t, I> { /// ``` /// and relates `?X` and `ty`. #[instrument(level = "debug", skip(self))] - fn relate_alias_ty( + fn relate_alias_term( &mut self, variance: Variance, alias: &AliasTy, - ty: &Ty, + term: &Term, ) -> Fallible<()> { let interner = self.interner; match variance { @@ -465,29 +469,44 @@ impl<'t, I: Interner> Unifier<'t, I> { self.environment, AliasEq { alias: alias.clone(), - term: Term::Ty(ty.clone()), + term: term.clone(), } .cast(interner), )); Ok(()) } - Variance::Covariant | Variance::Contravariant => { - // TODO need to convert this into type or const. - let term = self - .table - .new_variable(UniverseIndex::root()) - .to_ty(interner); - self.goals.push(InEnvironment::new( - self.environment, - AliasEq { - alias: alias.clone(), - term: Term::Ty(term.clone()), - } - .cast(interner), - )); - // TODO this should vary whether it relates a type or a const - self.relate_ty_ty(variance, &term, ty) - } + Variance::Covariant | Variance::Contravariant => match term { + Term::Ty(ty) => { + let var = self + .table + .new_variable(UniverseIndex::root()) + .to_ty(interner); + self.goals.push(InEnvironment::new( + self.environment, + AliasEq { + alias: alias.clone(), + term: Term::Ty(var.clone()), + } + .cast(interner), + )); + self.relate_ty_ty(variance, &var, ty) + } + Term::Const(ct) => { + let var = self + .table + .new_variable(UniverseIndex::root()) + .to_const(interner, ct.data(interner).ty.clone()); + self.goals.push(InEnvironment::new( + self.environment, + AliasEq { + alias: alias.clone(), + term: Term::Const(var.clone()), + } + .cast(interner), + )); + self.relate_const_const(variance, &var, ct) + } + }, } } @@ -631,7 +650,8 @@ impl<'t, I: Interner> Unifier<'t, I> { }) } WhereClause::AliasEq(alias_eq) => { - let AliasEq { alias, term: _ } = alias_eq; + let AliasEq { alias, term } = alias_eq; + assert!(matches!(term, Term::Ty(_))); let alias = match alias { AliasTy::Opaque(opaque_ty) => { let OpaqueTy { diff --git a/chalk-solve/src/logging_db/id_collector.rs b/chalk-solve/src/logging_db/id_collector.rs index 1f412de545e..afc635a749f 100644 --- a/chalk-solve/src/logging_db/id_collector.rs +++ b/chalk-solve/src/logging_db/id_collector.rs @@ -60,12 +60,12 @@ pub fn collect_unrecorded_ids>( let trait_datum = collector.db.trait_datum(trait_id); trait_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST); - for assoc_ty_id in &trait_datum.associated_ty_ids { - let assoc_ty_datum = collector.db.associated_term_data(*assoc_ty_id); - assoc_ty_datum + for assoc_id in &trait_datum.associated_term_ids { + let assoc_datum = collector.db.associated_term_data(*assoc_id); + assoc_datum .bounds_on_self(collector.db.interner()) .visit_with(&mut collector, DebruijnIndex::INNERMOST); - assoc_ty_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST); + assoc_datum.visit_with(&mut collector, DebruijnIndex::INNERMOST); } } RecordedItemId::OpaqueTy(opaque_id) => { diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index d2629234414..1723ff915d7 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -249,7 +249,8 @@ pub struct TraitDatum { /// chalk we add annotations like `#[auto]`. pub flags: TraitFlags, - pub associated_ty_ids: Vec>, + /// Types and consts associated with this trait. + pub associated_term_ids: Vec>, /// If this is a well-known trait, which one? If `None`, this is a regular, /// user-defined trait. @@ -529,6 +530,9 @@ pub struct AssociatedTermDatumBound { /// Where clauses that must hold for the projection to be well-formed. pub where_clauses: Vec>, + + /// If the associated term is a constant, what type is it? + pub assoc_const_ty: Option>, } impl AssociatedTermDatum { diff --git a/chalk-solve/src/wf.rs b/chalk-solve/src/wf.rs index e3f5b210a86..9d6e87becdd 100644 --- a/chalk-solve/src/wf.rs +++ b/chalk-solve/src/wf.rs @@ -618,6 +618,7 @@ fn compute_assoc_ty_goal( let AssociatedTermDatumBound { bounds: defn_bounds, where_clauses: defn_where_clauses, + assoc_const_ty: _, } = assoc_ty_datum .binders .clone() diff --git a/tests/integration/panic.rs b/tests/integration/panic.rs index 06725792bc5..872dbd7f768 100644 --- a/tests/integration/panic.rs +++ b/tests/integration/panic.rs @@ -81,7 +81,7 @@ impl RustIrDatabase for MockDatabase { non_enumerable: false, coinductive: false, }, - associated_ty_ids: vec![], + associated_term_ids: vec![], well_known: None, }) } diff --git a/tests/test/projection.rs b/tests/test/projection.rs index a80fe1b588c..3ddb604d135 100644 --- a/tests/test/projection.rs +++ b/tests/test/projection.rs @@ -1113,12 +1113,14 @@ fn const_projection() { test! { program { trait ConstTrait { const N: usize; } + struct Foo {} + impl ConstTrait for Foo { const N: usize = 3; } impl ConstTrait for () { const N: usize = 3; } impl ConstTrait for i32 { const N: usize = 5; } } goal { - ::N = 3 + ::N = 3 } yields { expect![[r#"No possible solution"#]] }