|
| 1 | +# cg meeting 2021-02-16 |
| 2 | + |
| 3 | +## issue |
| 4 | + |
| 5 | +1. 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`. |
| 6 | +2. 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. This breaks some programs, some of which already compile on stable. |
| 7 | +```rust |
| 8 | +fn bind<const N: usize>(value: [u8; N]) -> [u8; 3 + 4] { |
| 9 | + todo!() |
| 10 | +} |
| 11 | + |
| 12 | +fn main() { |
| 13 | + let mut arr: ?0 = Default::default(); |
| 14 | + arr = bind(arr); //~ ERROR mismatched type |
| 15 | + // ?0 = [u8; ?c2] |
| 16 | + // [u8; D<[u8; ?c2]>] <: [u8; ?c2] |
| 17 | + // D<[u8; ?c2]> = ?c2 |
| 18 | + // --> occurs check violation |
| 19 | +} |
| 20 | +``` |
| 21 | +and https://github.com/rust-lang/rust/issues/78369: |
| 22 | +```rust= |
| 23 | +#![feature(lazy_normalization_consts)] |
| 24 | +// `1 + 4` now "depends on T", preventing us from |
| 25 | +// being able to unsize `P` here. |
| 26 | +struct P<T: ?Sized>([u8; 1 + 4], T); |
| 27 | +
|
| 28 | +fn main() { |
| 29 | + let x: Box<P<[u8; 0]>> = Box::new(P(Default::default(), [0; 0])); |
| 30 | + let _: Box<P<[u8]>> = x; |
| 31 | +} |
| 32 | +``` |
| 33 | +## solution |
| 34 | + |
| 35 | +Eagerly filter the supplied generic params to the anonymous constant. |
| 36 | + |
| 37 | +- only depend on the predicates and parameters which can be used by the anon const based on what we know by looking at the `hir`. |
| 38 | + - using a graph |
| 39 | + - build a graph with parameters being nodes and an edge between 2 parameters if the target parameter can be reached by using the source parameter. |
| 40 | + - only add the parameters which are part of the reachable subgraph containing all explicitly mentioned parameters. |
| 41 | + - using relations |
| 42 | + - a relation `R` which holds for all params which are part of the same predicate |
| 43 | + - compute the transitive closure of `R` on the set of explicitly mentioned parameters |
| 44 | +- have to do all of this without looking at the parents `predicates_of` because that may contain our constant. |
| 45 | +- can a `U: Trait<T>` somehow "pull in" `U` if only `T` is explicitly used? |
| 46 | + - let's start with "yes". |
| 47 | +- should we consider `T` used because of `ConcreteTy: Trait<T>`? We currently do use that predicate for `ConcreteTy::ASSOC_CONST`. |
| 48 | + - probably yes. |
| 49 | +- would going from this approach to a more precise one be a breaking change? |
| 50 | + - with a high probability not. |
| 51 | +- DECISION: |
| 52 | + - DO IT |
0 commit comments