|
| 1 | +# cg meeting 09.02.2020 |
| 2 | + |
| 3 | +*mostly taken from https://hackmd.io/9LIywezOQj-h5HX8vvEnSw?view* |
| 4 | + |
| 5 | +Lazy norm deals with 2 different issues: |
| 6 | + |
| 7 | +- We must not typeck anonymous constants in some early queries, most notably `query type_of` and `query predicates_of`. Even if we were to use some hacks, there is a limit to how independent we can make this. One hard barrier is `query crate_variances`. |
| 8 | +- Delay unification of constants during typeck. An example for why this is necessary: |
| 9 | + - not relevant for today, skip |
| 10 | + - `D` is an anonymous constant with two generic parameters |
| 11 | + - We can not unify `D<$0, $2>` with `D<$1, $2>` |
| 12 | + - If `$0 = $1` we know that they are equal |
| 13 | + - Analogous to associated types |
| 14 | + - `<$0 as Trait<$2>>::X = <$1 as Trait<$2>>::X` |
| 15 | + - @lcnr: still not sure if this is actually necessary. |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +When using the `const_generics` feature gate, anonymous constants currently have all the generic parameters of their parent, even if they are unused inside of the constant. |
| 20 | + |
| 21 | +This breaks some programs, some of which already compile on stable. |
| 22 | + |
| 23 | +```rust |
| 24 | +// unused-subst-4 |
| 25 | +fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] { |
| 26 | + todo!() |
| 27 | +} |
| 28 | + |
| 29 | +fn main() { |
| 30 | + let mut arr: ?0 = Default::default(); |
| 31 | + arr = bind(arr); //~ ERROR mismatched type |
| 32 | + // ?0 = [u8; ?c2] |
| 33 | + // [u8; D<[u8; ?c2]>] <: [u8; ?c2] |
| 34 | + // D<[u8; ?c2]> = ?c2 |
| 35 | + // --> occurs check violation |
| 36 | +} |
| 37 | +``` |
| 38 | + |
| 39 | +Two solutions: |
| 40 | +- eagerly filter the supplied generic params to the anonymous constant |
| 41 | + * if we remove parameters that are not explicitly used, have to filter out the where-clauses |
| 42 | + * generating the `ty::Predicate` from the HIR (i.e., `predicates_of` query) |
| 43 | + * annoying thing about `T::Item` which is expanded to `<T as Trait<U>>::Item` |
| 44 | + * but that implies a `T: Trait<U>`, which would bring in `U` |
| 45 | + * will pull in too many parameters, still prevent some programs from compiling (e.g., `fn foo<T, U>() -> [u8; size_of::<T>()] where T: PartialEq<U>` will pull in `U` but it's not really needed) |
| 46 | + * back-compat when later improving the filtering? probably fine |
| 47 | + * additional weirdness` |
| 48 | +```rust |
| 49 | +pub trait Trait<T> { |
| 50 | + const ASSOC_CONST: usize = 0; |
| 51 | +} |
| 52 | + |
| 53 | +impl Trait<()> for u8 {} |
| 54 | + |
| 55 | +pub fn foo<T>() -> [T; u8::ASSOC_CONST] |
| 56 | +where |
| 57 | + u8: Trait<T>, |
| 58 | + // pulling in this predicate changes the way we resolve |
| 59 | + // `u8::ASSOC_CONST` here. |
| 60 | + // |
| 61 | + // Do we even want this, optionally change the way we |
| 62 | + // resolve associated constants in anonymous constants? |
| 63 | +{ |
| 64 | + todo!() |
| 65 | +} |
| 66 | +``` |
| 67 | +- start out with still using all generic parameters. Once we can `typeck` the anonymous constant, filter everything which is unused in the mir of the constant. |
| 68 | + - captures exactly the parameters which are needed |
| 69 | + - less self-contained than the first option |
| 70 | + - will we encounter cycles where type checking the anonymous constants needs to look at the anon const substs of itself? I think this is unlikely, but would prevent us from using this option. How likely is this? |
| 71 | + - requires further testing/exploration |
| 72 | + - In general, how do we deal with predicates on anonymous constants? Can we even use anonymous constants in ways which do not also require the predicates of the parent item? |
| 73 | + - Predicates required for well-formedness which get removed with this approach, not yet an issue, but maybe in the future. (https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/meeting.2009.2E02.2E2021/near/225715123) |
| 74 | +# end of meeting |
| 75 | +> - still have to modify `predicates_of` for anonymous constants, can't just use the parent ones, https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/lazy.20norm.20future.20compat/near/217663295 |
| 76 | +> |
| 77 | +># Optional stuff :sparkles: |
| 78 | +> |
| 79 | +>- https://rust-lang.zulipchat.com/#narrow/stream/260443-project-const-generics/topic/lazy.20norm.20recursive.20impls |
| 80 | +> - eagerly evaluate fully concrete anonymous constants? probably |
0 commit comments