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
.