--- title: Planning meeting 2023-05-03 tags: planning-meeting --- # T-lang meeting agenda * Meeting date: 2023-05-03 ## Attendance * Team members: * Others: ## Meeting roles * Action item scribe: * Note-taker: ## Meeting plan * May 10: [Language design principles](https://github.com/rust-lang/lang-team/issues/189), if niko pulls it off * May 17: [RPITIT stabilization discussion](https://github.com/rust-lang/lang-team/issues/207) * May 24: [Keyword Generics Initiative Update](https://github.com/rust-lang/lang-team/issues/203) * May 31: [TAIT defining scope options](https://github.com/rust-lang/lang-team/issues/206) * nikomatsakis/tmandry to help organize to find an owner for doc ## Meeting topics of interest * https://github.com/rust-lang/lang-team/issues/207 * [TAIT defining scope options](https://github.com/rust-lang/lang-team/issues/206) * TC wrote a [summary](https://github.com/rust-lang/lang-team/issues/206#issuecomment-1522500410) * Possible focus topics for meeting * Clarifying *requirements* on the design * e.g. is it different *within* an impl vs within a module? * how much do we truly care about the IDE constraints? * what are the interactions with cycles? * People it would be good to have weigh in * rust-analyzer developers * oli-obk * cramertj, lang team, etc * Can we ship something about use of `impl Trait` in associated types? * What design do we actually want for *TAITs*? ## Random digression: async fn / RPITIT ```rust trait Foo { async fn method(&self, input: Cell<&Input>); } trait Foo { fn method<'a, 'b, 'c>( &'a self, input: Cell<&'b Input>, input: Cell<&'c Input>, ) -> impl Future<Output = ()> + 'a + 'b + 'c; // ------- too strong // This forces the hidden type to outlive 'a, 'b, and 'c // If the hidden type is `Generator<&'a self, Cell<&'b Input>, ...>' then `'a: 'a + 'b + 'c` // and `'b: 'a + 'b + 'c` and so forth. // // But we don't know that `'b: 'c` and because // they are invariant we can't play with variance, // which would cause borrow check errors anyhow. } ``` You can do the captures trick: ```rust trait Foo { async fn method(&self, input: Cell<&Input>); } trait Captures<T> { } impl<T, U> Captures<T> for U { } trait Foo { fn method<'a, 'b, 'c>( &'a self, input: Cell<&'b Input>, input: Cell<&'c Input>, ) -> impl Future<Output = ()> + Captures<(&'a(), &'b(), &'c())>; } impl Foo for () { async fn method(&self, ...) { } } ``` ```rust type Foo<'a, 'b, 'c> = impl Future<Output = ()>; // in olden days, this would capture all lifetimes in scope and hence have same semantics ``` ```rust trait Foo { type Method<'a, 'b, 'c>: Future<Output = ()>; fn method<'a, 'b, 'c>( &'a self, input: Cell<&'b Input>, input: Cell<&'c Input>, ) -> Self::Method<'a, 'b, 'c>; } impl Foo for Bar { type Method<'a, 'b, 'c> = impl Future<...> /* but how do I deal with captures here */ ; } ``` ```rust trait Foo { fn method<'a, 'b, 'c>( &'a self, input: Cell<&'b Input>, input: Cell<&'c Input>, ) -> impl Future<Output = ()> + ('a & 'b & 'c); ```