It seems array does not implement the Index trait, if so , how can we index it? It is treated specially by compiler ?
so when the coerce happened ? at A or B? It seems the type of a is [i32;3].
let a = [1,2,3]; // A
a[1]; // B
It happens at B.
Coercion also happens at method calls, so you can call slice methods like a.get(1)
.
The indexing syntax a[1]
is shorthand for a method call, *a.index(1)
.
I'm curious about the detail. So I dived into the compiler code, if at this line , the type of base
is a slice it will explain it, but I can not figure out how type of base
is corece to a slice.
Actually, arrays are kinda special and index access is done directly by the compiler and no coercion happens. If you access the array out-of-bounds, you'll get an unconditional panic compile-time error, which can be turned off and the resulting code will simply have a test
call directly, instead of calling Index::index
.
#![allow(unconditional_panic)]
fn main() {
let a = [1, 2, 3];
dbg!(a[3]);
}
will turn into
playground::main:
pushq %rbx
subq $304, %rsp
xorl %eax, %eax
movl $1, 104(%rsp)
movl $2, 108(%rsp)
movl $3, 112(%rsp)
testb $1, %al
jne .LBB18_1
jmp .LBB18_8
.LBB18_1:
movl 116(%rsp), %eax
movl %eax, 116(%rsp)
movq .L__unnamed_2(%rip), %rcx
movq .L__unnamed_3(%rip), %rdx
movq .L__unnamed_4(%rip), %rsi
movq .L__unnamed_5(%rip), %rdi
leaq 116(%rsp), %r8
movq %r8, 264(%rsp)
movq %rdx, 232(%rsp)
movq %rsi, 240(%rsp)
movq %rdi, 248(%rsp)
leaq 264(%rsp), %rdx
movq %rdx, 256(%rsp)
movq 232(%rsp), %rdx
movq %rdx, 272(%rsp)
movq 240(%rsp), %rsi
movq %rsi, 280(%rsp)
movq 248(%rsp), %rdi
movq %rdi, 288(%rsp)
movq 256(%rsp), %r8
movq %r8, 296(%rsp)
movq %rdi, 96(%rsp)
movq %rdx, %rdi
leaq <&T as core::fmt::Display>::fmt(%rip), %rdx
movq %rsi, 88(%rsp)
movq %rdx, %rsi
movq %rcx, 80(%rsp)
movq %r8, 72(%rsp)
callq core::fmt::ArgumentV1::new
movq %rax, 64(%rsp)
movq %rdx, 56(%rsp)
movq core::fmt::num::imp::<impl core::fmt::Display for u32>::fmt@GOTPCREL(%rip), %rsi
movq 88(%rsp), %rdi
callq core::fmt::ArgumentV1::new
movq %rax, 48(%rsp)
movq %rdx, 40(%rsp)
movq 96(%rsp), %rdi
leaq <&T as core::fmt::Display>::fmt(%rip), %rsi
callq core::fmt::ArgumentV1::new
movq %rax, 32(%rsp)
movq %rdx, 24(%rsp)
movq 72(%rsp), %rdi
leaq <&T as core::fmt::Debug>::fmt(%rip), %rsi
callq core::fmt::ArgumentV1::new
movq %rax, 16(%rsp)
movq %rdx, 8(%rsp)
movq 64(%rsp), %rax
movq %rax, 168(%rsp)
movq 56(%rsp), %rcx
movq %rcx, 176(%rsp)
movq 48(%rsp), %rdx
movq %rdx, 184(%rsp)
movq 40(%rsp), %rsi
movq %rsi, 192(%rsp)
movq 32(%rsp), %rdi
movq %rdi, 200(%rsp)
movq 24(%rsp), %r8
movq %r8, 208(%rsp)
movq 16(%rsp), %r9
movq %r9, 216(%rsp)
movq 8(%rsp), %r10
movq %r10, 224(%rsp)
leaq 168(%rsp), %r11
movq .L__unnamed_6(%rip), %rbx
leaq 120(%rsp), %rdi
movq 80(%rsp), %rsi
movl $5, %edx
movq %r11, %rcx
movl $4, %r8d
movq %rbx, %r9
movq $4, (%rsp)
callq core::fmt::Arguments::new_v1_formatted
leaq 120(%rsp), %rdi
callq *std::io::stdio::_eprint@GOTPCREL(%rip)
addq $304, %rsp
popq %rbx
retq
.LBB18_8:
leaq .L__unnamed_7(%rip), %rdx
movq core::panicking::panic_bounds_check@GOTPCREL(%rip), %rax
movl $3, %ecx
movq %rcx, %rdi
movq %rcx, %rsi
callq *%rax
ud2
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.