aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
authorJade <[email protected]>2021-05-14 08:59:30 +0100
committerJade <[email protected]>2021-05-14 09:39:28 +0100
commit78d6b88f211cc9faf88815ce7fb1a91546cfce15 (patch)
tree6b54a10d2eeee6fc03d63015e4b7c9838b4b02b9 /crates/hir_def
parent32c600664e5a599bbe3f0254274211474b89914a (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')
-rw-r--r--crates/hir_def/src/type_ref.rs12
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
328impl ConstScalar { 338impl 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) => {