diff --git a/chalk-integration/src/lowering.rs b/chalk-integration/src/lowering.rs index f3d1f0dee77..331e47df782 100644 --- a/chalk-integration/src/lowering.rs +++ b/chalk-integration/src/lowering.rs @@ -98,6 +98,8 @@ lower_param_map!(ClosureDefn, None); lower_param_map!(Impl, None); lower_param_map!(AssocTyDefn, None); lower_param_map!(AssocTyValue, None); +lower_param_map!(AssocConstDefn, None); +lower_param_map!(AssocConstValue, None); lower_param_map!(Clause, None); lower_param_map!( TraitDefn, diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index e5d477981cb..2118751d944 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -340,6 +340,20 @@ impl ProgramLowerer { AssocItemDefn::Const(assoc_const_defn) => { let lookup = &self.associated_const_lookups [&(trait_id, assoc_const_defn.name.str.clone())]; + + let mut variable_kinds = assoc_const_defn.all_parameters(); + variable_kinds.extend(trait_defn.all_parameters()); + + let value = assoc_const_defn + .value + .as_ref() + .map(|value| { + empty_env.in_binders(variable_kinds, |env| { + Ok(value.lower(&env)?) + }) + }) + .transpose()?; + associated_const_data.insert( lookup.id, Arc::new(rust_ir::AssociatedConstDatum { @@ -347,11 +361,7 @@ impl ProgramLowerer { id: lookup.id, name: assoc_const_defn.name.str.clone(), ty: assoc_const_defn.ty.lower(&empty_env)?, - value: assoc_const_defn - .value - .clone() - .map(|v| v.lower(&empty_env)) - .transpose()?, + value, }), ); } diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index db07b89d183..cf6b69fbac3 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -206,6 +206,7 @@ pub struct AssocTyDefn { #[derive(Clone, PartialEq, Eq, Debug)] pub struct AssocConstDefn { pub name: Identifier, + pub variable_kinds: Vec, pub ty: Ty, pub value: Option, } @@ -341,6 +342,7 @@ pub struct AssocTyValue { #[derive(Clone, PartialEq, Eq, Debug)] pub struct AssocConstValue { pub name: Identifier, + pub variable_kinds: Vec, pub ty: Ty, pub value: Const, } diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index c2e198af061..d01c27a5b6b 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -290,10 +290,11 @@ AssocTyDefn: AssocTyDefn = { }; AssocConstDefn: AssocConstDefn = { - "const" ":" )?> ";" => + "const" > ":" )?> ";" => { AssocConstDefn { name, + variable_kinds: p, ty, value } @@ -404,10 +405,11 @@ AssocTyValue: AssocTyValue = { }; AssocConstValue: AssocConstValue = { - "const" ":" "=" ";" => + "const" > ":" "=" ";" => { AssocConstValue { name, + variable_kinds: a, ty, value, } diff --git a/chalk-solve/src/logging_db/id_collector.rs b/chalk-solve/src/logging_db/id_collector.rs index f820a80f8da..dc127ceb138 100644 --- a/chalk-solve/src/logging_db/id_collector.rs +++ b/chalk-solve/src/logging_db/id_collector.rs @@ -9,7 +9,7 @@ use chalk_ir::{ use std::collections::BTreeSet; /// Collects the identifiers needed to resolve all the names for a given -/// set of identifers, excluding identifiers we already have. +/// set of identifiers, excluding identifiers we already have. /// /// When recording identifiers to print, the `LoggingRustIrDatabase` only /// records identifiers the solver uses. But the solver assumes well-formedness, diff --git a/chalk-solve/src/rust_ir.rs b/chalk-solve/src/rust_ir.rs index 4af82a110c2..f8da2a359f2 100644 --- a/chalk-solve/src/rust_ir.rs +++ b/chalk-solve/src/rust_ir.rs @@ -514,7 +514,13 @@ impl Visit for AssociatedTyDatum { } } -/// Represents an associated const declaration found inside of a trait. +/// Represents an associated const declaration found inside of a trait: +/// +/// ```notrust +/// trait Foo { // P0 is Self +/// const Bar: [type] (= [const]); +/// } +/// ``` #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct AssociatedConstDatum { /// The trait this associated const is defined in. @@ -530,7 +536,7 @@ pub struct AssociatedConstDatum { pub ty: Ty, /// Value of this associated const. - pub value: Option>, + pub value: Option>>, } // Manual implementation to avoid I::Identifier type.