diff --git a/chalk-integration/src/lowering/program_lowerer.rs b/chalk-integration/src/lowering/program_lowerer.rs index a5dc18df640..2659301b878 100644 --- a/chalk-integration/src/lowering/program_lowerer.rs +++ b/chalk-integration/src/lowering/program_lowerer.rs @@ -152,6 +152,7 @@ impl ProgramLowerer { let mut closure_upvars = BTreeMap::new(); let mut trait_data = BTreeMap::new(); let mut well_known_traits = BTreeMap::new(); + let mut well_known_assoc_types = BTreeMap::new(); let mut impl_data = BTreeMap::new(); let mut associated_ty_data = BTreeMap::new(); let mut associated_ty_values = BTreeMap::new(); @@ -272,6 +273,15 @@ impl ProgramLowerer { let lookup = &self.associated_ty_lookups [&(trait_id, assoc_ty_defn.name.str.clone())]; + if let Some(well_known) = assoc_ty_defn.well_known { + let well_known = match well_known { + chalk_parse::ast::WellKnownAssocType::AsyncFnOnceOutput => { + chalk_solve::rust_ir::WellKnownAssocType::AsyncFnOnceOutput + } + }; + well_known_assoc_types.insert(well_known, lookup.id); + } + // The parameters in scope for the associated // type definitions are *both* those from the // trait *and* those from the associated type @@ -494,6 +504,7 @@ impl ProgramLowerer { coroutine_witness_data, trait_data, well_known_traits, + well_known_assoc_types, impl_data, associated_ty_values, associated_ty_data, diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 2444de91946..ebf205140af 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -11,7 +11,7 @@ use chalk_ir::{ use chalk_solve::rust_ir::{ AdtDatum, AdtRepr, AdtSizeAlign, AssociatedTyDatum, AssociatedTyValue, AssociatedTyValueId, ClosureKind, CoroutineDatum, CoroutineWitnessDatum, FnDefDatum, FnDefInputsAndOutputDatum, - ImplDatum, ImplType, OpaqueTyDatum, TraitDatum, WellKnownTrait, + ImplDatum, ImplType, OpaqueTyDatum, TraitDatum, WellKnownAssocType, WellKnownTrait, }; use chalk_solve::split::Split; use chalk_solve::RustIrDatabase; @@ -96,6 +96,9 @@ pub struct Program { /// For each trait lang item pub well_known_traits: BTreeMap>, + /// For each assoc type lang item + pub well_known_assoc_types: BTreeMap>, + /// For each associated ty declaration `type Foo` found in a trait: pub associated_ty_data: BTreeMap, Arc>>, @@ -539,10 +542,9 @@ impl RustIrDatabase for Program { fn well_known_assoc_type_id( &self, - _assoc_type: chalk_solve::rust_ir::WellKnownAssocType, + assoc_type: WellKnownAssocType, ) -> Option> { - // FIXME - None + self.well_known_assoc_types.get(&assoc_type).copied() } fn program_clauses_for_env( diff --git a/chalk-ir/src/debug.rs b/chalk-ir/src/debug.rs index 8aa48d7de25..e57185bb034 100644 --- a/chalk-ir/src/debug.rs +++ b/chalk-ir/src/debug.rs @@ -152,17 +152,13 @@ impl Debug for QuantifiedWhereClauses { impl Debug for ProjectionTy { 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") - }) + I::debug_projection_ty(self, fmt).unwrap_or_else(|| fmt.write_str("")) } } impl Debug for OpaqueTy { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { - I::debug_opaque_ty(self, fmt).unwrap_or_else(|| { - unimplemented!("cannot format OpaqueTy without setting Program in tls") - }) + I::debug_opaque_ty(self, fmt).unwrap_or_else(|| fmt.write_str("")) } } diff --git a/chalk-parse/src/ast.rs b/chalk-parse/src/ast.rs index 4e9758f3b25..38464f1e4b1 100644 --- a/chalk-parse/src/ast.rs +++ b/chalk-parse/src/ast.rs @@ -187,6 +187,12 @@ pub struct AssocTyDefn { pub variable_kinds: Vec, pub bounds: Vec, pub where_clauses: Vec, + pub well_known: Option, +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum WellKnownAssocType { + AsyncFnOnceOutput, } #[derive(Clone, PartialEq, Eq, Debug)] diff --git a/chalk-parse/src/parser.lalrpop b/chalk-parse/src/parser.lalrpop index 9631ff09187..3aba81b220c 100644 --- a/chalk-parse/src/parser.lalrpop +++ b/chalk-parse/src/parser.lalrpop @@ -283,7 +283,12 @@ TraitDefn: TraitDefn = { } }; +WellKnownAssocType: WellKnownAssocType = { + "#" "[" "lang" "(" "async_fn_once_output" ")" "]" => WellKnownAssocType::AsyncFnOnceOutput, +}; + AssocTyDefn: AssocTyDefn = { + "type" > >)?> ";" => { @@ -292,6 +297,7 @@ AssocTyDefn: AssocTyDefn = { variable_kinds: p, where_clauses: w, bounds: b.unwrap_or(vec![]), + well_known, } } }; diff --git a/tests/test/closures.rs b/tests/test/closures.rs index 4bfdfdbc1de..f0aa6ed13e1 100644 --- a/tests/test/closures.rs +++ b/tests/test/closures.rs @@ -170,6 +170,7 @@ fn closure_implements_fn_traits() { #[lang(async_fn_once)] trait AsyncFnOnce { type CallOnceFuture: Future>::Output>; + #[lang(async_fn_once_output)] type Output; } diff --git a/tests/test/fn_def.rs b/tests/test/fn_def.rs index 6dcee8bc494..193d47dc201 100644 --- a/tests/test/fn_def.rs +++ b/tests/test/fn_def.rs @@ -88,6 +88,7 @@ fn fn_def_implements_fn_traits() { #[lang(async_fn_once)] trait AsyncFnOnce { type CallOnceFuture: Future>::Output>; + #[lang(async_fn_once_output)] type Output; } @@ -209,6 +210,7 @@ fn generic_fn_implements_fn_traits() { #[lang(async_fn_once)] trait AsyncFnOnce { type CallOnceFuture: Future>::Output>; + #[lang(async_fn_once_output)] type Output; } diff --git a/tests/test/functions.rs b/tests/test/functions.rs index e7c10a7216d..b8ef1da5e44 100644 --- a/tests/test/functions.rs +++ b/tests/test/functions.rs @@ -67,6 +67,7 @@ fn function_implement_fn_traits() { #[lang(async_fn_once)] trait AsyncFnOnce { type CallOnceFuture: Future>::Output>; + #[lang(async_fn_once_output)] type Output; }