From ebe1d8ec2a685a846941cbe605a58c162bacf8ae Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 20 May 2014 18:20:26 -0700 Subject: [PATCH 1/3] Add run-pass case for issue #14308 Enum wildcard patterns in match behave wrong when applied to tuple structs. They either ICE or cause an LLVM error. --- src/test/run-pass/issue-14308.rs | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/test/run-pass/issue-14308.rs diff --git a/src/test/run-pass/issue-14308.rs b/src/test/run-pass/issue-14308.rs new file mode 100644 index 000000000000..0e4b4a2c9cf3 --- /dev/null +++ b/src/test/run-pass/issue-14308.rs @@ -0,0 +1,32 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct A(int); +struct B; + +fn main() { + let x = match A(3) { + A(..) => 1 + }; + assert_eq!(x, 1); + let x = match A(4) { + A(1) => 1, + A(..) => 2 + }; + assert_eq!(x, 2); + + // This next test uses a (..) wildcard match on a nullary struct. + // There's no particularly good reason to support this, but it's currently allowed, + // and this makes sure it doesn't ICE or break LLVM. + let x = match B { + B(..) => 3 + }; + assert_eq!(x, 3); +} From d5b5aa4d4a11a15bab4dbb31e029a807cb1d4ad3 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 20 May 2014 16:57:44 -0700 Subject: [PATCH 2/3] Fix ICE regarding tuple struct matches using (..) Fixes half of #14308. --- src/librustc/middle/trans/_match.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index e609da6c33dd..d9eec2056d88 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -810,6 +810,9 @@ fn enter_tuple_struct<'a, 'b>( ast::PatEnum(_, Some(ref elts)) => { Some(elts.iter().map(|x| (*x)).collect()) } + ast::PatEnum(_, None) => { + Some(Vec::from_elem(n_elts, dummy)) + } _ => { assert_is_binding_or_wild(bcx, p); Some(Vec::from_elem(n_elts, dummy)) From 0718259ae05e661c7f62bac6a02c6cba80d3f1f9 Mon Sep 17 00:00:00 2001 From: Kevin Ballard Date: Tue, 20 May 2014 19:18:20 -0700 Subject: [PATCH 3/3] Fix LLVM error with tuple struct match using (..) Consider PatEnums constructed with A(..) to be candidates for tuple struct patterns, not just ones constructed with A(a,b,c). If these patterns shouldn't be valid tuple struct patterns (as they're equivalent to _), this needs to be caught before we get to trans. Fixes #14308. --- src/librustc/middle/trans/_match.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index d9eec2056d88..4a96439e0ec5 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -1120,7 +1120,7 @@ fn any_tuple_struct_pat(bcx: &Block, m: &[Match], col: uint) -> bool { m.iter().any(|br| { let pat = *br.pats.get(col); match pat.node { - ast::PatEnum(_, Some(_)) => { + ast::PatEnum(_, _) => { match bcx.tcx().def_map.borrow().find(&pat.id) { Some(&ast::DefFn(..)) | Some(&ast::DefStruct(..)) => true,