Support const args in type dependent paths (Take 2) by lcnr · Pull Request #74113 · rust-lang/rust (original) (raw)

once more, except it is sound this time 🥰 previously #71154


#![feature(const_generics)]

struct A; impl A { fn foo(&self) -> usize { N } } struct B; impl B { fn foo(&self) -> usize { 42 } }

fn main() { let a = A; a.foo::<7>(); }

When calling type_of for generic const arguments, we now use the TypeckTables of the surrounding body to get the expected type.

This alone causes cycle errors though, as we now have typeck_tables_of(main) -> ... ->
type_of(main_ANON0 := 7) -> typeck_tables_of(main) ⚡ (see #68400 (comment))

To prevent this we must not call type_of(const_arg) during typeck_tables_of. This is achieved by
calling type_of(param_def_id) instead.

We have to somehow remember the DefId of the param through all of typeck, which is done using the
struct ty::WithOptConstParam<DefId>, which replaces DefId where needed and contains an Option<DefId> to
be able to store the const parameter in case it exists.

Queries which are currently cached on disk are split into two variants: query_name(cached) and query_name_(of|for)_const_arg(not cached), with query_name_of_const_arg taking a pair (did, param_did): (LocalDefId, DefId).

For some queries a method query_name_of_opt_const_arg is added to TyCtxt which takes a ty::WithOptConstParam and either calls query_name or query_name_of_const_arg depending on the value of const_param_did.

r? @eddyb @varkor