aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty
diff options
context:
space:
mode:
authorJade <[email protected]>2021-05-12 12:39:48 +0100
committerJade <[email protected]>2021-05-13 05:22:46 +0100
commit8b147624ff906a11134d2e18be071c6cb8ec4beb (patch)
tree28df73a940497bc170ec9f080329657f4b1370b8 /crates/hir_ty
parent312f1fe20a6a0a8e69834c66f51b9abc9db5e0ce (diff)
Add lowering of array lengths in types
Now e.g. ```rust fn a(b: [u8; 2]) { } ``` will know about the length of b.
Diffstat (limited to 'crates/hir_ty')
-rw-r--r--crates/hir_ty/src/consts.rs21
-rw-r--r--crates/hir_ty/src/display.rs5
-rw-r--r--crates/hir_ty/src/infer/expr.rs8
-rw-r--r--crates/hir_ty/src/interner.rs3
-rw-r--r--crates/hir_ty/src/lib.rs9
-rw-r--r--crates/hir_ty/src/lower.rs26
-rw-r--r--crates/hir_ty/src/tests/coercion.rs44
-rw-r--r--crates/hir_ty/src/tests/patterns.rs8
-rw-r--r--crates/hir_ty/src/tests/simple.rs16
9 files changed, 64 insertions, 76 deletions
diff --git a/crates/hir_ty/src/consts.rs b/crates/hir_ty/src/consts.rs
deleted file mode 100644
index 0044b1cff..000000000
--- a/crates/hir_ty/src/consts.rs
+++ /dev/null
@@ -1,21 +0,0 @@
1//! Handling of concrete const values
2
3/// A concrete constant value
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
5pub enum ConstScalar {
6 // for now, we only support the trivial case of constant evaluating the length of an array
7 // Note that this is u64 because the target usize may be bigger than our usize
8 Usize(u64),
9
10 /// Case of an unknown value that rustc might know but we don't
11 Unknown,
12}
13
14impl std::fmt::Display for ConstScalar {
15 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
16 match self {
17 ConstScalar::Usize(us) => write!(fmt, "{}", us),
18 ConstScalar::Unknown => write!(fmt, "_"),
19 }
20 }
21}
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 8a4296697..7bbd1a1f7 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -962,11 +962,10 @@ impl HirDisplay for TypeRef {
962 write!(f, "{}", mutability)?; 962 write!(f, "{}", mutability)?;
963 inner.hir_fmt(f)?; 963 inner.hir_fmt(f)?;
964 } 964 }
965 TypeRef::Array(inner) => { 965 TypeRef::Array(inner, len) => {
966 write!(f, "[")?; 966 write!(f, "[")?;
967 inner.hir_fmt(f)?; 967 inner.hir_fmt(f)?;
968 // FIXME: Array length? 968 write!(f, "; {}]", len)?;
969 write!(f, "; _]")?;
970 } 969 }
971 TypeRef::Slice(inner) => { 970 TypeRef::Slice(inner) => {
972 write!(f, "[")?; 971 write!(f, "[")?;
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 2178ffd07..5e9420752 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -8,6 +8,7 @@ use hir_def::{
8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp}, 8 expr::{Array, BinaryOp, Expr, ExprId, Literal, Statement, UnaryOp},
9 path::{GenericArg, GenericArgs}, 9 path::{GenericArg, GenericArgs},
10 resolver::resolver_for_expr, 10 resolver::resolver_for_expr,
11 type_ref::ConstScalar,
11 AssocContainerId, FieldId, Lookup, 12 AssocContainerId, FieldId, Lookup,
12}; 13};
13use hir_expand::name::{name, Name}; 14use hir_expand::name::{name, Name};
@@ -15,9 +16,7 @@ use stdx::always;
15use syntax::ast::RangeOp; 16use syntax::ast::RangeOp;
16 17
17use crate::{ 18use crate::{
18 autoderef, 19 autoderef, dummy_usize_const,
19 consts::ConstScalar,
20 dummy_usize_const,
21 lower::lower_to_chalk_mutability, 20 lower::lower_to_chalk_mutability,
22 mapping::from_chalk, 21 mapping::from_chalk,
23 method_resolution, op, 22 method_resolution, op,
@@ -737,7 +736,8 @@ impl<'a> InferenceContext<'a> {
737 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner), 736 TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
738 ), 737 ),
739 ); 738 );
740 // FIXME: support length for Repeat array expressions 739 // FIXME: we don't know the length here because hir Exprs don't actually
740 // get the value out of the AST, even though it is there.
741 None 741 None
742 } 742 }
743 }; 743 };
diff --git a/crates/hir_ty/src/interner.rs b/crates/hir_ty/src/interner.rs
index 4cbc9cd4f..7b4119747 100644
--- a/crates/hir_ty/src/interner.rs
+++ b/crates/hir_ty/src/interner.rs
@@ -1,11 +1,12 @@
1//! Implementation of the Chalk `Interner` trait, which allows customizing the 1//! Implementation of the Chalk `Interner` trait, which allows customizing the
2//! representation of the various objects Chalk deals with (types, goals etc.). 2//! representation of the various objects Chalk deals with (types, goals etc.).
3 3
4use crate::{chalk_db, consts::ConstScalar, tls, GenericArg}; 4use crate::{chalk_db, tls, GenericArg};
5use base_db::salsa::InternId; 5use base_db::salsa::InternId;
6use chalk_ir::{Goal, GoalData}; 6use chalk_ir::{Goal, GoalData};
7use hir_def::{ 7use hir_def::{
8 intern::{impl_internable, InternStorage, Internable, Interned}, 8 intern::{impl_internable, InternStorage, Internable, Interned},
9 type_ref::ConstScalar,
9 TypeAliasId, 10 TypeAliasId,
10}; 11};
11use smallvec::SmallVec; 12use smallvec::SmallVec;
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index d23eff513..be3f55bdf 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -12,7 +12,6 @@ mod chalk_db;
12mod chalk_ext; 12mod chalk_ext;
13mod infer; 13mod infer;
14mod interner; 14mod interner;
15mod consts;
16mod lower; 15mod lower;
17mod mapping; 16mod mapping;
18mod op; 17mod op;
@@ -38,9 +37,13 @@ use chalk_ir::{
38 interner::HasInterner, 37 interner::HasInterner,
39 UintTy, 38 UintTy,
40}; 39};
41use hir_def::{expr::ExprId, type_ref::Rawness, TypeParamId}; 40use hir_def::{
41 expr::ExprId,
42 type_ref::{ConstScalar, Rawness},
43 TypeParamId,
44};
42 45
43use crate::{consts::ConstScalar, db::HirDatabase, display::HirDisplay, utils::generics}; 46use crate::{db::HirDatabase, display::HirDisplay, utils::generics};
44 47
45pub use autoderef::autoderef; 48pub use autoderef::autoderef;
46pub use builder::TyBuilder; 49pub use builder::TyBuilder;
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 9751b45e4..f7015e5ff 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -9,7 +9,9 @@ use std::cell::{Cell, RefCell};
9use std::{iter, sync::Arc}; 9use std::{iter, sync::Arc};
10 10
11use base_db::CrateId; 11use base_db::CrateId;
12use chalk_ir::{cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety}; 12use chalk_ir::{
13 cast::Cast, fold::Shift, interner::HasInterner, Mutability, Safety, Scalar, UintTy,
14};
13use hir_def::{ 15use hir_def::{
14 adt::StructKind, 16 adt::StructKind,
15 body::{Expander, LowerCtx}, 17 body::{Expander, LowerCtx},
@@ -30,16 +32,15 @@ use syntax::ast;
30 32
31use crate::{ 33use crate::{
32 db::HirDatabase, 34 db::HirDatabase,
33 dummy_usize_const,
34 mapping::ToChalk, 35 mapping::ToChalk,
35 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx, 36 static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
36 utils::{ 37 utils::{
37 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics, 38 all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
38 }, 39 },
39 AliasEq, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, DynTy, FnPointer, FnSig, 40 AliasEq, AliasTy, Binders, BoundVar, CallableSig, ConstData, ConstValue, DebruijnIndex, DynTy,
40 FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy, QuantifiedWhereClause, 41 FnPointer, FnSig, FnSubst, ImplTraitId, Interner, OpaqueTy, PolyFnSig, ProjectionTy,
41 QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits, Substitution, 42 QuantifiedWhereClause, QuantifiedWhereClauses, ReturnTypeImplTrait, ReturnTypeImplTraits,
42 TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause, 43 Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyBuilder, TyKind, WhereClause,
43}; 44};
44 45
45#[derive(Debug)] 46#[derive(Debug)]
@@ -172,11 +173,16 @@ impl<'a> TyLoweringContext<'a> {
172 let inner_ty = self.lower_ty(inner); 173 let inner_ty = self.lower_ty(inner);
173 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner) 174 TyKind::Raw(lower_to_chalk_mutability(*mutability), inner_ty).intern(&Interner)
174 } 175 }
175 TypeRef::Array(inner) => { 176 TypeRef::Array(inner, len) => {
176 let inner_ty = self.lower_ty(inner); 177 let inner_ty = self.lower_ty(inner);
177 // FIXME: we don't have length info here because we don't store an expression for 178
178 // the length 179 let const_len = ConstData {
179 TyKind::Array(inner_ty, dummy_usize_const()).intern(&Interner) 180 ty: TyKind::Scalar(Scalar::Uint(UintTy::Usize)).intern(&Interner),
181 value: ConstValue::Concrete(chalk_ir::ConcreteConst { interned: *len }),
182 }
183 .intern(&Interner);
184
185 TyKind::Array(inner_ty, const_len).intern(&Interner)
180 } 186 }
181 TypeRef::Slice(inner) => { 187 TypeRef::Slice(inner) => {
182 let inner_ty = self.lower_ty(inner); 188 let inner_ty = self.lower_ty(inner);
diff --git a/crates/hir_ty/src/tests/coercion.rs b/crates/hir_ty/src/tests/coercion.rs
index aad3d610e..c2afaf6ec 100644
--- a/crates/hir_ty/src/tests/coercion.rs
+++ b/crates/hir_ty/src/tests/coercion.rs
@@ -64,42 +64,42 @@ fn coerce_places() {
64 81..92 '{ loop {} }': T 64 81..92 '{ loop {} }': T
65 83..90 'loop {}': ! 65 83..90 'loop {}': !
66 88..90 '{}': () 66 88..90 '{}': ()
67 121..132 '{ loop {} }': *mut [T; _] 67 121..132 '{ loop {} }': *mut [T; 2]
68 123..130 'loop {}': ! 68 123..130 'loop {}': !
69 128..130 '{}': () 69 128..130 '{}': ()
70 159..172 '{ gen() }': *mut [U] 70 159..172 '{ gen() }': *mut [U]
71 165..168 'gen': fn gen<U>() -> *mut [U; _] 71 165..168 'gen': fn gen<U>() -> *mut [U; 2]
72 165..170 'gen()': *mut [U; _] 72 165..170 'gen()': *mut [U; 2]
73 185..419 '{ ...rr); }': () 73 185..419 '{ ...rr); }': ()
74 195..198 'arr': &[u8; _] 74 195..198 'arr': &[u8; 1]
75 211..215 '&[1]': &[u8; 1] 75 211..215 '&[1]': &[u8; 1]
76 212..215 '[1]': [u8; 1] 76 212..215 '[1]': [u8; 1]
77 213..214 '1': u8 77 213..214 '1': u8
78 226..227 'a': &[u8] 78 226..227 'a': &[u8]
79 236..239 'arr': &[u8; _] 79 236..239 'arr': &[u8; 1]
80 249..250 'b': u8 80 249..250 'b': u8
81 253..254 'f': fn f<u8>(&[u8]) -> u8 81 253..254 'f': fn f<u8>(&[u8]) -> u8
82 253..259 'f(arr)': u8 82 253..259 'f(arr)': u8
83 255..258 'arr': &[u8; _] 83 255..258 'arr': &[u8; 1]
84 269..270 'c': &[u8] 84 269..270 'c': &[u8]
85 279..286 '{ arr }': &[u8] 85 279..286 '{ arr }': &[u8]
86 281..284 'arr': &[u8; _] 86 281..284 'arr': &[u8; 1]
87 296..297 'd': u8 87 296..297 'd': u8
88 300..301 'g': fn g<u8>(S<&[u8]>) -> u8 88 300..301 'g': fn g<u8>(S<&[u8]>) -> u8
89 300..315 'g(S { a: arr })': u8 89 300..315 'g(S { a: arr })': u8
90 302..314 'S { a: arr }': S<&[u8]> 90 302..314 'S { a: arr }': S<&[u8]>
91 309..312 'arr': &[u8; _] 91 309..312 'arr': &[u8; 1]
92 325..326 'e': [&[u8]; _] 92 325..326 'e': [&[u8]; 1]
93 340..345 '[arr]': [&[u8]; 1] 93 340..345 '[arr]': [&[u8]; 1]
94 341..344 'arr': &[u8; _] 94 341..344 'arr': &[u8; 1]
95 355..356 'f': [&[u8]; _] 95 355..356 'f': [&[u8]; 2]
96 370..378 '[arr; 2]': [&[u8]; _] 96 370..378 '[arr; 2]': [&[u8]; _]
97 371..374 'arr': &[u8; _] 97 371..374 'arr': &[u8; 1]
98 376..377 '2': usize 98 376..377 '2': usize
99 388..389 'g': (&[u8], &[u8]) 99 388..389 'g': (&[u8], &[u8])
100 406..416 '(arr, arr)': (&[u8], &[u8]) 100 406..416 '(arr, arr)': (&[u8], &[u8])
101 407..410 'arr': &[u8; _] 101 407..410 'arr': &[u8; 1]
102 412..415 'arr': &[u8; _] 102 412..415 'arr': &[u8; 1]
103 "#]], 103 "#]],
104 ); 104 );
105} 105}
@@ -159,7 +159,7 @@ fn infer_custom_coerce_unsized() {
159 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {} 159 impl<'a, 'b: 'a, T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<&'a U> for &'b T {}
160 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {} 160 impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<*mut U> for *mut T {}
161 "#, 161 "#,
162 expect![[r" 162 expect![[r#"
163 257..258 'x': A<[T]> 163 257..258 'x': A<[T]>
164 278..283 '{ x }': A<[T]> 164 278..283 '{ x }': A<[T]>
165 280..281 'x': A<[T]> 165 280..281 'x': A<[T]>
@@ -169,23 +169,23 @@ fn infer_custom_coerce_unsized() {
169 333..334 'x': C<[T]> 169 333..334 'x': C<[T]>
170 354..359 '{ x }': C<[T]> 170 354..359 '{ x }': C<[T]>
171 356..357 'x': C<[T]> 171 356..357 'x': C<[T]>
172 369..370 'a': A<[u8; _]> 172 369..370 'a': A<[u8; 2]>
173 384..385 'b': B<[u8; _]> 173 384..385 'b': B<[u8; 2]>
174 399..400 'c': C<[u8; _]> 174 399..400 'c': C<[u8; 2]>
175 414..480 '{ ...(c); }': () 175 414..480 '{ ...(c); }': ()
176 424..425 'd': A<[{unknown}]> 176 424..425 'd': A<[{unknown}]>
177 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]> 177 428..432 'foo1': fn foo1<{unknown}>(A<[{unknown}]>) -> A<[{unknown}]>
178 428..435 'foo1(a)': A<[{unknown}]> 178 428..435 'foo1(a)': A<[{unknown}]>
179 433..434 'a': A<[u8; _]> 179 433..434 'a': A<[u8; 2]>
180 445..446 'e': B<[u8]> 180 445..446 'e': B<[u8]>
181 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]> 181 449..453 'foo2': fn foo2<u8>(B<[u8]>) -> B<[u8]>
182 449..456 'foo2(b)': B<[u8]> 182 449..456 'foo2(b)': B<[u8]>
183 454..455 'b': B<[u8; _]> 183 454..455 'b': B<[u8; 2]>
184 466..467 'f': C<[u8]> 184 466..467 'f': C<[u8]>
185 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]> 185 470..474 'foo3': fn foo3<u8>(C<[u8]>) -> C<[u8]>
186 470..477 'foo3(c)': C<[u8]> 186 470..477 'foo3(c)': C<[u8]>
187 475..476 'c': C<[u8; _]> 187 475..476 'c': C<[u8; 2]>
188 "]], 188 "#]],
189 ); 189 );
190} 190}
191 191
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 33305f208..b36e77e91 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -345,19 +345,19 @@ fn infer_pattern_match_arr() {
345 "#, 345 "#,
346 expect![[r#" 346 expect![[r#"
347 10..179 '{ ... } }': () 347 10..179 '{ ... } }': ()
348 20..23 'arr': [f64; _] 348 20..23 'arr': [f64; 2]
349 36..46 '[0.0, 1.0]': [f64; 2] 349 36..46 '[0.0, 1.0]': [f64; 2]
350 37..40 '0.0': f64 350 37..40 '0.0': f64
351 42..45 '1.0': f64 351 42..45 '1.0': f64
352 52..177 'match ... }': () 352 52..177 'match ... }': ()
353 58..61 'arr': [f64; _] 353 58..61 'arr': [f64; 2]
354 72..80 '[1.0, a]': [f64; _] 354 72..80 '[1.0, a]': [f64; 2]
355 73..76 '1.0': f64 355 73..76 '1.0': f64
356 73..76 '1.0': f64 356 73..76 '1.0': f64
357 78..79 'a': f64 357 78..79 'a': f64
358 84..110 '{ ... }': () 358 84..110 '{ ... }': ()
359 98..99 'a': f64 359 98..99 'a': f64
360 120..126 '[b, c]': [f64; _] 360 120..126 '[b, c]': [f64; 2]
361 121..122 'b': f64 361 121..122 'b': f64
362 124..125 'c': f64 362 124..125 'c': f64
363 130..171 '{ ... }': () 363 130..171 '{ ... }': ()
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index 8b09f2e4a..19775a4ec 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1313,7 +1313,7 @@ fn infer_array() {
1313 255..256 'a': [&str; 1] 1313 255..256 'a': [&str; 1]
1314 258..263 '["b"]': [&str; 1] 1314 258..263 '["b"]': [&str; 1]
1315 259..262 '"b"': &str 1315 259..262 '"b"': &str
1316 274..275 'x': [u8; _] 1316 274..275 'x': [u8; 0]
1317 287..289 '[]': [u8; 0] 1317 287..289 '[]': [u8; 0]
1318 "#]], 1318 "#]],
1319 ); 1319 );
@@ -2409,38 +2409,38 @@ fn infer_operator_overload() {
2409 320..422 '{ ... }': V2 2409 320..422 '{ ... }': V2
2410 334..335 'x': f32 2410 334..335 'x': f32
2411 338..342 'self': V2 2411 338..342 'self': V2
2412 338..344 'self.0': [f32; _] 2412 338..344 'self.0': [f32; 2]
2413 338..347 'self.0[0]': {unknown} 2413 338..347 'self.0[0]': {unknown}
2414 338..358 'self.0...s.0[0]': f32 2414 338..358 'self.0...s.0[0]': f32
2415 345..346 '0': i32 2415 345..346 '0': i32
2416 350..353 'rhs': V2 2416 350..353 'rhs': V2
2417 350..355 'rhs.0': [f32; _] 2417 350..355 'rhs.0': [f32; 2]
2418 350..358 'rhs.0[0]': {unknown} 2418 350..358 'rhs.0[0]': {unknown}
2419 356..357 '0': i32 2419 356..357 '0': i32
2420 372..373 'y': f32 2420 372..373 'y': f32
2421 376..380 'self': V2 2421 376..380 'self': V2
2422 376..382 'self.0': [f32; _] 2422 376..382 'self.0': [f32; 2]
2423 376..385 'self.0[1]': {unknown} 2423 376..385 'self.0[1]': {unknown}
2424 376..396 'self.0...s.0[1]': f32 2424 376..396 'self.0...s.0[1]': f32
2425 383..384 '1': i32 2425 383..384 '1': i32
2426 388..391 'rhs': V2 2426 388..391 'rhs': V2
2427 388..393 'rhs.0': [f32; _] 2427 388..393 'rhs.0': [f32; 2]
2428 388..396 'rhs.0[1]': {unknown} 2428 388..396 'rhs.0[1]': {unknown}
2429 394..395 '1': i32 2429 394..395 '1': i32
2430 406..408 'V2': V2([f32; _]) -> V2 2430 406..408 'V2': V2([f32; 2]) -> V2
2431 406..416 'V2([x, y])': V2 2431 406..416 'V2([x, y])': V2
2432 409..415 '[x, y]': [f32; 2] 2432 409..415 '[x, y]': [f32; 2]
2433 410..411 'x': f32 2433 410..411 'x': f32
2434 413..414 'y': f32 2434 413..414 'y': f32
2435 436..519 '{ ... vb; }': () 2435 436..519 '{ ... vb; }': ()
2436 446..448 'va': V2 2436 446..448 'va': V2
2437 451..453 'V2': V2([f32; _]) -> V2 2437 451..453 'V2': V2([f32; 2]) -> V2
2438 451..465 'V2([0.0, 1.0])': V2 2438 451..465 'V2([0.0, 1.0])': V2
2439 454..464 '[0.0, 1.0]': [f32; 2] 2439 454..464 '[0.0, 1.0]': [f32; 2]
2440 455..458 '0.0': f32 2440 455..458 '0.0': f32
2441 460..463 '1.0': f32 2441 460..463 '1.0': f32
2442 475..477 'vb': V2 2442 475..477 'vb': V2
2443 480..482 'V2': V2([f32; _]) -> V2 2443 480..482 'V2': V2([f32; 2]) -> V2
2444 480..494 'V2([0.0, 1.0])': V2 2444 480..494 'V2([0.0, 1.0])': V2
2445 483..493 '[0.0, 1.0]': [f32; 2] 2445 483..493 '[0.0, 1.0]': [f32; 2]
2446 484..487 '0.0': f32 2446 484..487 '0.0': f32