diff options
author | Jade <[email protected]> | 2021-05-14 08:59:30 +0100 |
---|---|---|
committer | Jade <[email protected]> | 2021-05-14 09:39:28 +0100 |
commit | 78d6b88f211cc9faf88815ce7fb1a91546cfce15 (patch) | |
tree | 6b54a10d2eeee6fc03d63015e4b7c9838b4b02b9 /crates/hir_def/src | |
parent | 32c600664e5a599bbe3f0254274211474b89914a (diff) |
Add more tests, refactor array lengths/consteval work
Fix #2922: add unknown length as a condition for a type having unknown.
Incorporate reviews:
* Extract some of the const evaluation workings into functions
* Add fixmes on the hacks
* Add tests for impls on specific array lengths (these work!!! 😁)
* Add tests for const generics (indeed we don't support it yet)
Diffstat (limited to 'crates/hir_def/src')
-rw-r--r-- | crates/hir_def/src/type_ref.rs | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index 00c09a23d..6a3259b27 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs | |||
@@ -80,6 +80,8 @@ pub enum TypeRef { | |||
80 | Path(Path), | 80 | Path(Path), |
81 | RawPtr(Box<TypeRef>, Mutability), | 81 | RawPtr(Box<TypeRef>, Mutability), |
82 | Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability), | 82 | Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability), |
83 | // FIXME: for full const generics, the latter element (length) here is going to have to be an | ||
84 | // expression that is further lowered later in hir_ty. | ||
83 | Array(Box<TypeRef>, ConstScalar), | 85 | Array(Box<TypeRef>, ConstScalar), |
84 | Slice(Box<TypeRef>), | 86 | Slice(Box<TypeRef>), |
85 | /// A fn pointer. Last element of the vector is the return type. | 87 | /// A fn pointer. Last element of the vector is the return type. |
@@ -141,6 +143,10 @@ impl TypeRef { | |||
141 | TypeRef::RawPtr(Box::new(inner_ty), mutability) | 143 | TypeRef::RawPtr(Box::new(inner_ty), mutability) |
142 | } | 144 | } |
143 | ast::Type::ArrayType(inner) => { | 145 | ast::Type::ArrayType(inner) => { |
146 | // FIXME: This is a hack. We should probably reuse the machinery of | ||
147 | // `hir_def::body::lower` to lower this into an `Expr` and then evaluate it at the | ||
148 | // `hir_ty` level, which would allow knowing the type of: | ||
149 | // let v: [u8; 2 + 2] = [0u8; 4]; | ||
144 | let len = inner | 150 | let len = inner |
145 | .expr() | 151 | .expr() |
146 | .map(ConstScalar::usize_from_literal_expr) | 152 | .map(ConstScalar::usize_from_literal_expr) |
@@ -313,6 +319,10 @@ pub enum ConstScalar { | |||
313 | Usize(u64), | 319 | Usize(u64), |
314 | 320 | ||
315 | /// Case of an unknown value that rustc might know but we don't | 321 | /// Case of an unknown value that rustc might know but we don't |
322 | // FIXME: this is a hack to get around chalk not being able to represent unevaluatable | ||
323 | // constants | ||
324 | // https://github.com/rust-analyzer/rust-analyzer/pull/8813#issuecomment-840679177 | ||
325 | // https://rust-lang.zulipchat.com/#narrow/stream/144729-wg-traits/topic/Handling.20non.20evaluatable.20constants'.20equality/near/238386348 | ||
316 | Unknown, | 326 | Unknown, |
317 | } | 327 | } |
318 | 328 | ||
@@ -326,6 +336,8 @@ impl std::fmt::Display for ConstScalar { | |||
326 | } | 336 | } |
327 | 337 | ||
328 | impl ConstScalar { | 338 | impl ConstScalar { |
339 | // FIXME: as per the comments on `TypeRef::Array`, this evaluation should not happen at this | ||
340 | // parse stage. | ||
329 | fn usize_from_literal_expr(expr: ast::Expr) -> ConstScalar { | 341 | fn usize_from_literal_expr(expr: ast::Expr) -> ConstScalar { |
330 | match expr { | 342 | match expr { |
331 | ast::Expr::Literal(lit) => { | 343 | ast::Expr::Literal(lit) => { |