Closed
Description
Possibly the treatment as a match vs. a binding is inconsistent between typeck and trans. The unused variable lint is also peculiar.
macro_rules! foo {
($n:expr) => {
match $n {
zzzz @ _ => zzzz + 1,
_ => 0,
}
}
}
fn main() {
const zzzz: i32 = 3;
assert_eq!(foo!(3), 4);
}
$ rustc --version
rustc 1.0.0-dev (4db0b3246 2015-02-25) (built 2015-02-26)
$ rustc -C debuginfo=2 foo.rs # only happens w/o opt
foo.rs:4:13: 4:21 warning: unused variable: `zzzz`, #[warn(unused_variables)] on by default
foo.rs:4 zzzz @ _ => zzzz + 1,
^~~~~~~~
foo.rs:1:1: 8:2 note: in expansion of foo!
foo.rs:12:16: 12:24 note: expansion site
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
foo.rs:12:5: 12:28 note: expansion site
foo.rs:11:5: 11:25 warning: constant `zzzz` should have an upper case name such as `ZZZZ`, #[warn(non_upper_case_globals)] on by default
foo.rs:11 const zzzz: i32 = 3;
^~~~~~~~~~~~~~~~~~~~
foo.rs:4:13: 4:21 warning: constant in pattern `zzzz` should have an upper case name such as `ZZZZ`, #[warn(non_upper_case_globals)] on by default
foo.rs:4 zzzz @ _ => zzzz + 1,
^~~~~~~~
foo.rs:1:1: 8:2 note: in expansion of foo!
foo.rs:12:16: 12:24 note: expansion site
<std macros>:1:1: 9:39 note: in expansion of assert_eq!
foo.rs:12:5: 12:28 note: expansion site
$ gdb ./foo
(gdb) run
Starting program: /tmp/foo
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000555555559146 in foo::main () at foo.rs:10
10 fn main() {
IR:
; ModuleID = 'foo.0.rs'
target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
%str_slice = type { i8*, i64 }
%"2.core::fmt::Formatter" = type { i32, i32, i8, %"2.core::option::Option<usize>", %"2.core::option::Option<usize>", { i8*, void (i8*)** }, %"2.core::slice::Iter<core::fmt::ArgumentV1>", { %"2.core::fmt::ArgumentV1"*, i64 } }
%"2.core::option::Option<usize>" = type { i64, [0 x i64], [1 x i64] }
%"2.core::slice::Iter<core::fmt::ArgumentV1>" = type { %"2.core::fmt::ArgumentV1"*, %"2.core::fmt::ArgumentV1"*, %"2.core::marker::PhantomData<&'static core::fmt::ArgumentV1>" }
%"2.core::fmt::ArgumentV1" = type { %"2.core::fmt::Void"*, i8 (%"2.core::fmt::Void"*, %"2.core::fmt::Formatter"*)* }
%"2.core::fmt::Void" = type {}
%"2.core::marker::PhantomData<&'static core::fmt::ArgumentV1>" = type {}
%"2.core::fmt::Arguments" = type { { %str_slice*, i64 }, %"2.core::option::Option<&'static [core::fmt::rt::v1::Argument]>", { %"2.core::fmt::ArgumentV1"*, i64 } }
%"2.core::option::Option<&'static [core::fmt::rt::v1::Argument]>" = type { { %"2.core::fmt::rt::v1::Argument"*, i64 } }
%"2.core::fmt::rt::v1::Argument" = type { %"2.core::fmt::rt::v1::Position", %"2.core::fmt::rt::v1::FormatSpec" }
%"2.core::fmt::rt::v1::Position" = type { i64, [0 x i64], [1 x i64] }
%"2.core::fmt::rt::v1::FormatSpec" = type { i32, i8, i32, %"2.core::fmt::rt::v1::Count", %"2.core::fmt::rt::v1::Count" }
%"2.core::fmt::rt::v1::Count" = type { i64, [0 x i64], [1 x i64] }
@const19 = internal unnamed_addr constant i32 3
@const22 = internal unnamed_addr constant i32 4
@const26 = internal unnamed_addr constant i32 0
@const27 = internal unnamed_addr constant i32* @const22
@const133 = internal unnamed_addr constant { { i8*, i8* } } zeroinitializer
@str1146 = internal constant [63 x i8] c"assertion failed: `(left == right) && (right == left)` (left: `"
@str1147 = internal constant [11 x i8] c"`, right: `"
@str1148 = internal constant [2 x i8] c"`)"
@ref68 = internal unnamed_addr constant [3 x %str_slice] [%str_slice { i8* getelementptr inbounds ([63 x i8]* @str1146, i32 0, i32 0), i64 63 }, %str_slice { i8* getelementptr inbounds ([11 x i8]* @str1147, i32 0, i32 0), i64 11 }, %str_slice { i8* getelementptr inbounds ([2 x i8]* @str1148, i32 0, i32 0), i64 2 }]
@_ZN4main15__STATIC_FMTSTR20h0eec925d33596e3a9aaE = internal constant { %str_slice*, i64 } { %str_slice* getelementptr inbounds ([3 x %str_slice]* @ref68, i32 0, i32 0), i64 3 }
@const90 = internal unnamed_addr constant i8 (i32*, %"2.core::fmt::Formatter"*)* @_ZN3fmt3num14i32.fmt..Debug3fmt20h82571085d6d53e2c8uBE
@str1159 = internal constant [6 x i8] c"foo.rs"
@_ZN4main10_FILE_LINE20ha7672bc1aa8c4e82KbaE = internal constant { %str_slice, i64 } { %str_slice { i8* getelementptr inbounds ([6 x i8]* @str1159, i32 0, i32 0), i64 6 }, i64 12 }
; Function Attrs: uwtable
define internal void @_ZN4main20hd61647c88ae5d91beaaE() unnamed_addr #0 {
entry-block:
%0 = alloca { i32*, i32* }
%1 = alloca i32
%match = alloca i32
%__llmatch = alloca i32*
%zzzz = alloca i32
%addr_of = alloca i32
%__llmatch3 = alloca i32**
%left_val = alloca i32*
%__llmatch4 = alloca i32**
%right_val = alloca i32*
%2 = alloca %"2.core::fmt::Arguments"
%3 = alloca { %str_slice*, i64 }
%4 = alloca [2 x %"2.core::fmt::ArgumentV1"]
%5 = alloca { i32*, i32* }
%__llmatch7 = alloca i32**
%__arg0 = alloca i32*
%__llmatch8 = alloca i32**
%__arg1 = alloca i32*
%auto_deref = alloca [2 x %"2.core::fmt::ArgumentV1"]*
%__fat_ptr = alloca { %"2.core::fmt::ArgumentV1"*, i64 }
%__fat_ptr10 = alloca { %"2.core::fmt::ArgumentV1"*, i64 }
%6 = alloca { %str_slice, i64 }*
%7 = getelementptr inbounds { i32*, i32* }* %0, i32 0, i32 0
store i32 3, i32* %match
%8 = load i32* %match
switch i32 %8, label %match_else [
i32 3, label %match_case
]
case_body: ; preds = %match_case
%9 = load i32** %__llmatch
%10 = load i32* %9
store i32 %10, i32* %zzzz
store i32 4, i32* %1
br label %join
case_body1: ; preds = %match_else
store i32 0, i32* %1
br label %join
match_else: ; preds = %entry-block
br label %case_body1
match_case: ; preds = %entry-block
br label %case_body
join: ; preds = %case_body1, %case_body
%11 = load i32* %1
store i32 %11, i32* %addr_of
store i32* %addr_of, i32** %7
%12 = getelementptr inbounds { i32*, i32* }* %0, i32 0, i32 1
store i32* @const22, i32** %12
%13 = getelementptr inbounds { i32*, i32* }* %0, i32 0, i32 0
%14 = getelementptr inbounds { i32*, i32* }* %0, i32 0, i32 1
store i32** %13, i32*** %__llmatch3
store i32** %14, i32*** %__llmatch4
br label %case_body2
case_body2: ; preds = %join
%15 = load i32*** %__llmatch3
%16 = load i32** %15, !nonnull !0
store i32* %16, i32** %left_val
%17 = load i32*** %__llmatch4
%18 = load i32** %17, !nonnull !0
store i32* %18, i32** %right_val
%19 = load i32** %left_val, !nonnull !0
%20 = load i32** %right_val, !nonnull !0
%21 = load i32* %19
%22 = load i32* %20
%23 = icmp eq i32 %21, %22
br i1 %23, label %before_rhs, label %join5
join5: ; preds = %before_rhs, %case_body2
%24 = phi i1 [ %23, %case_body2 ], [ %30, %before_rhs ]
%25 = xor i1 %24, true
br i1 %25, label %then-block-51-, label %next-block
before_rhs: ; preds = %case_body2
%26 = load i32** %right_val, !nonnull !0
%27 = load i32** %left_val, !nonnull !0
%28 = load i32* %26
%29 = load i32* %27
%30 = icmp eq i32 %28, %29
br label %join5
then-block-51-: ; preds = %join5
%31 = bitcast { %str_slice*, i64 }* %3 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %31, i8* bitcast ({ %str_slice*, i64 }* @_ZN4main15__STATIC_FMTSTR20h0eec925d33596e3a9aaE to i8*), i64 16, i32 8, i1 false)
%32 = getelementptr inbounds { i32*, i32* }* %5, i32 0, i32 0
%33 = load i32** %left_val, !nonnull !0
store i32* %33, i32** %32
%34 = getelementptr inbounds { i32*, i32* }* %5, i32 0, i32 1
%35 = load i32** %right_val, !nonnull !0
store i32* %35, i32** %34
%36 = getelementptr inbounds { i32*, i32* }* %5, i32 0, i32 0
%37 = getelementptr inbounds { i32*, i32* }* %5, i32 0, i32 1
store i32** %36, i32*** %__llmatch7
store i32** %37, i32*** %__llmatch8
br label %case_body6
case_body6: ; preds = %then-block-51-
%38 = load i32*** %__llmatch8
%39 = load i32** %38, !nonnull !0
store i32* %39, i32** %__arg1
%40 = load i32*** %__llmatch7
%41 = load i32** %40, !nonnull !0
store i32* %41, i32** %__arg0
%42 = getelementptr inbounds [2 x %"2.core::fmt::ArgumentV1"]* %4, i32 0, i32 0
%43 = getelementptr inbounds %"2.core::fmt::ArgumentV1"* %42, i32 0
%44 = load i32** %__arg0, !nonnull !0
call void @"_ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h11701018729727839244E"(%"2.core::fmt::ArgumentV1"* noalias nocapture sret dereferenceable(16) %43, i32* noalias readonly dereferenceable(4) %44, i8 (i32*, %"2.core::fmt::Formatter"*)* @_ZN3fmt3num14i32.fmt..Debug3fmt20h82571085d6d53e2c8uBE)
%45 = getelementptr inbounds %"2.core::fmt::ArgumentV1"* %42, i32 1
%46 = load i32** %__arg1, !nonnull !0
call void @"_ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h11701018729727839244E"(%"2.core::fmt::ArgumentV1"* noalias nocapture sret dereferenceable(16) %45, i32* noalias readonly dereferenceable(4) %46, i8 (i32*, %"2.core::fmt::Formatter"*)* @_ZN3fmt3num14i32.fmt..Debug3fmt20h82571085d6d53e2c8uBE)
br label %join9
join9: ; preds = %case_body6
store [2 x %"2.core::fmt::ArgumentV1"]* %4, [2 x %"2.core::fmt::ArgumentV1"]** %auto_deref
%47 = load [2 x %"2.core::fmt::ArgumentV1"]** %auto_deref, !nonnull !0
%48 = bitcast [2 x %"2.core::fmt::ArgumentV1"]* %47 to %"2.core::fmt::ArgumentV1"*
%49 = getelementptr inbounds { %"2.core::fmt::ArgumentV1"*, i64 }* %__fat_ptr, i32 0, i32 0
store %"2.core::fmt::ArgumentV1"* %48, %"2.core::fmt::ArgumentV1"** %49
%50 = getelementptr inbounds { %"2.core::fmt::ArgumentV1"*, i64 }* %__fat_ptr, i32 0, i32 1
store i64 2, i64* %50
%51 = bitcast { %"2.core::fmt::ArgumentV1"*, i64 }* %__fat_ptr to i8*
%52 = bitcast { %"2.core::fmt::ArgumentV1"*, i64 }* %__fat_ptr10 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %52, i8* %51, i64 16, i32 8, i1 false)
call void @"_ZN3fmt23Arguments$LT$$u27$a$GT$6new_v120hddb70f9412632ed662BE"(%"2.core::fmt::Arguments"* noalias nocapture sret dereferenceable(48) %2, { %str_slice*, i64 }* noalias nocapture dereferenceable(16) %3, { %"2.core::fmt::ArgumentV1"*, i64 }* noalias nocapture dereferenceable(16) %__fat_ptr10)
store { %str_slice, i64 }* @_ZN4main10_FILE_LINE20ha7672bc1aa8c4e82KbaE, { %str_slice, i64 }** %6
%53 = load { %str_slice, i64 }** %6, !nonnull !0
call void @_ZN2rt6unwind16begin_unwind_fmt20hbda8d92395aa47d1LOIE(%"2.core::fmt::Arguments"* noalias nocapture dereferenceable(48) %2, { %str_slice, i64 }* noalias readonly dereferenceable(24) %53)
unreachable
next-block: ; preds = %join5
br label %join11
join11: ; preds = %next-block
ret void
}
define i64 @main(i64, i8**) unnamed_addr #1 {
top:
%2 = call i64 @_ZN2rt10lang_start20h7a2fc813423057b2l4IE(i8* bitcast (void ()* @_ZN4main20hd61647c88ae5d91beaaE to i8*), i64 %0, i8** %1)
ret i64 %2
}
declare i64 @_ZN2rt10lang_start20h7a2fc813423057b2l4IE(i8*, i64, i8**) unnamed_addr #1
; Function Attrs: cold noinline noreturn
declare void @_ZN2rt6unwind16begin_unwind_fmt20hbda8d92395aa47d1LOIE(%"2.core::fmt::Arguments"* noalias nocapture dereferenceable(48), { %str_slice, i64 }* noalias readonly dereferenceable(24)) unnamed_addr #2
; Function Attrs: inlinehint uwtable
define internal void @"_ZN3fmt23Arguments$LT$$u27$a$GT$6new_v120hddb70f9412632ed662BE"(%"2.core::fmt::Arguments"* noalias nocapture sret dereferenceable(48), { %str_slice*, i64 }* noalias nocapture dereferenceable(16), { %"2.core::fmt::ArgumentV1"*, i64 }* noalias nocapture dereferenceable(16)) unnamed_addr #3 {
entry-block:
%3 = getelementptr inbounds %"2.core::fmt::Arguments"* %0, i32 0, i32 0
%4 = bitcast { %str_slice*, i64 }* %1 to i8*
%5 = bitcast { %str_slice*, i64 }* %3 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %5, i8* %4, i64 16, i32 8, i1 false)
%6 = getelementptr inbounds %"2.core::fmt::Arguments"* %0, i32 0, i32 1
%7 = bitcast %"2.core::option::Option<&'static [core::fmt::rt::v1::Argument]>"* %6 to { { i8*, i8* } }*
%8 = bitcast { { i8*, i8* } }* %7 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %8, i8* bitcast ({ { i8*, i8* } }* @const133 to i8*), i64 16, i32 8, i1 false)
%9 = getelementptr inbounds %"2.core::fmt::Arguments"* %0, i32 0, i32 2
%10 = bitcast { %"2.core::fmt::ArgumentV1"*, i64 }* %2 to i8*
%11 = bitcast { %"2.core::fmt::ArgumentV1"*, i64 }* %9 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %11, i8* %10, i64 16, i32 8, i1 false)
ret void
}
; Function Attrs: nounwind
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1) unnamed_addr #4
; Function Attrs: uwtable
define internal void @"_ZN3fmt24ArgumentV1$LT$$u27$a$GT$3new21h11701018729727839244E"(%"2.core::fmt::ArgumentV1"* noalias nocapture sret dereferenceable(16), i32* noalias readonly dereferenceable(4), i8 (i32*, %"2.core::fmt::Formatter"*)*) unnamed_addr #0 {
entry-block:
%x = alloca i32*
%f = alloca i8 (i32*, %"2.core::fmt::Formatter"*)*
store i32* %1, i32** %x
store i8 (i32*, %"2.core::fmt::Formatter"*)* %2, i8 (i32*, %"2.core::fmt::Formatter"*)** %f
%3 = getelementptr inbounds %"2.core::fmt::ArgumentV1"* %0, i32 0, i32 1
%4 = load i8 (i32*, %"2.core::fmt::Formatter"*)** %f
%5 = bitcast i8 (i32*, %"2.core::fmt::Formatter"*)* %4 to i8 (%"2.core::fmt::Void"*, %"2.core::fmt::Formatter"*)*
store i8 (%"2.core::fmt::Void"*, %"2.core::fmt::Formatter"*)* %5, i8 (%"2.core::fmt::Void"*, %"2.core::fmt::Formatter"*)** %3
%6 = getelementptr inbounds %"2.core::fmt::ArgumentV1"* %0, i32 0, i32 0
%7 = load i32** %x, !nonnull !0
%8 = bitcast i32* %7 to %"2.core::fmt::Void"*
store %"2.core::fmt::Void"* %8, %"2.core::fmt::Void"** %6
ret void
}
declare i8 @_ZN3fmt3num14i32.fmt..Debug3fmt20h82571085d6d53e2c8uBE(i32* noalias readonly dereferenceable(4), %"2.core::fmt::Formatter"* noalias dereferenceable(96)) unnamed_addr #1
attributes #0 = { uwtable "split-stack" }
attributes #1 = { "split-stack" }
attributes #2 = { cold noinline noreturn "split-stack" }
attributes #3 = { inlinehint uwtable "split-stack" }
attributes #4 = { nounwind "split-stack" }
!0 = !{}