implement pattern-binding-modes RFC

See the [RFC] and [tracking issue].

[tracking issue]: https://github.com/rust-lang/rust/issues/42640
[RFC]: 491e0af/text/2005-match-ergonomics.md
This commit is contained in:
Tobias Schottdorf 2017-10-06 16:30:23 -04:00
parent a8feaee5b6
commit de55b4f077
46 changed files with 1406 additions and 75 deletions

View file

@ -0,0 +1,16 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub fn main() {
match &Some(3) {
Some(n) => {}, //~ ERROR mismatched types [E0308]
_ => panic!(),
}
}

View file

@ -9,7 +9,8 @@
// except according to those terms.
fn main() {
for (ref i,) in [].iter() { //~ ERROR mismatched types
// NB: this (almost) typechecks when default binding modes are enabled.
for (ref i,) in [].iter() { //~ ERROR mismatched types [E0308]
i.clone();
}
}

View file

@ -21,17 +21,4 @@ fn main() {
//~| expected tuple, found enum `A`
_ => ()
}
match &Some(42) {
Some(x) => (),
//~^ ERROR mismatched types
//~| expected type `&std::option::Option<{integer}>`
//~| found type `std::option::Option<_>`
//~| expected reference, found enum `std::option::Option`
None => ()
//~^ ERROR mismatched types
//~| expected type `&std::option::Option<{integer}>`
//~| found type `std::option::Option<_>`
//~| expected reference, found enum `std::option::Option`
}
}

View file

@ -17,8 +17,9 @@ fn main() {
_ => { }
};
// Note that this one works with default binding modes.
match &[0, 1, 2] {
[..] => {} //~ ERROR expected an array or slice, found `&[{integer}; 3]`
[..] => {} //~ ERROR expected an array or slice, found `&[{integer}; 3]` [E0529]
};
match &[0, 1, 2] {

View file

@ -10,13 +10,19 @@
#![feature(slice_patterns)]
// NB: this test was introduced in #23121 and will have to change when default match binding modes
// stabilizes.
fn slice_pat(x: &[u8]) {
// OLD!
match x {
[a, b..] => {}
[a, b..] => {},
//~^ ERROR expected an array or slice, found `&[u8]`
//~| HELP the semantics of slice patterns changed recently; see issue #23121
_ => panic!(),
}
}
fn main() {}
fn main() {
slice_pat("foo".as_bytes());
}

View file

@ -0,0 +1,27 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(box_syntax, box_patterns)]
#![feature(match_default_bindings)]
struct Foo{}
pub fn main() {
let b = box Foo{};
let box f = &b;
let _: &Foo = f;
match &&&b {
box f => {
let _: &Foo = f;
},
_ => panic!(),
}
}

View file

@ -0,0 +1,51 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
const CONST_REF: &[u8; 3] = b"foo";
trait Foo {
const CONST_REF_DEFAULT: &'static [u8; 3] = b"bar";
const CONST_REF: &'static [u8; 3];
}
impl Foo for i32 {
const CONST_REF: &'static [u8; 3] = b"jjj";
}
impl Foo for i64 {
const CONST_REF_DEFAULT: &'static [u8; 3] = b"ggg";
const CONST_REF: &'static [u8; 3] = b"fff";
}
// Check that (associated and free) const references are not mistaken for a
// non-reference pattern (in which case they would be auto-dereferenced, making
// the types mismatched).
fn const_ref() -> bool {
let f = b"foo";
match f {
CONST_REF => true,
_ => false,
}
}
fn associated_const_ref() -> bool {
match (b"bar", b"jjj", b"ggg", b"fff") {
(i32::CONST_REF_DEFAULT, i32::CONST_REF, i64::CONST_REF_DEFAULT, i64::CONST_REF) => true,
_ => false,
}
}
pub fn main() {
assert!(const_ref());
assert!(associated_const_ref());
}

View file

@ -0,0 +1,56 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
enum Wrapper {
Wrap(i32),
}
use Wrapper::Wrap;
pub fn main() {
let Wrap(x) = &Wrap(3);
println!("{}", *x);
let Wrap(x) = &mut Wrap(3);
println!("{}", *x);
if let Some(x) = &Some(3) {
println!("{}", *x);
} else {
panic!();
}
if let Some(x) = &mut Some(3) {
println!("{}", *x);
} else {
panic!();
}
if let Some(x) = &mut Some(3) {
*x += 1;
} else {
panic!();
}
while let Some(x) = &Some(3) {
println!("{}", *x);
break;
}
while let Some(x) = &mut Some(3) {
println!("{}", *x);
break;
}
while let Some(x) = &mut Some(3) {
*x += 1;
break;
}
}

View file

@ -0,0 +1,31 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
pub fn main() {
let mut tups = vec![(0u8, 1u8)];
for (n, m) in &tups {
let _: &u8 = n;
let _: &u8 = m;
}
for (n, m) in &mut tups {
*n += 1;
*m += 2;
}
assert_eq!(tups, vec![(1u8, 3u8)]);
for (n, m) in tups {
println!("{} {}", m, n);
}
}

View file

@ -0,0 +1,259 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
fn some_or_wildcard(r: &Option<i32>, b: &i32) {
let _: &i32 = match r {
Some(a) => a,
_ => b,
};
}
fn none_or_wildcard(r: &Option<i32>, b: &i32) {
let _: &i32 = match r {
None => b,
_ => b,
};
}
fn some_or_ref_none(r: &Option<i32>, b: &i32) {
let _: &i32 = match r {
Some(a) => a,
&None => b,
};
}
fn ref_some_or_none(r: &Option<i32>, b: &i32) {
let _: &i32 = match r {
&Some(ref a) => a,
None => b,
};
}
fn some_or_self(r: &Option<i32>) {
let _: &Option<i32> = match r {
Some(n) => {
let _: &i32 = n;
r
},
x => x,
};
}
fn multiple_deref(r: &&&&&Option<i32>) {
let _: i32 = match r {
Some(a) => *a,
None => 5,
};
}
fn match_with_or() {
// FIXME(tschottdorf): #44912.
//
// let x = &Some((3, 3));
// let _: &i32 = match x {
// Some((x, 3)) | &Some((ref x, 5)) => x,
// _ => &5i32,
// };
}
fn nested_mixed() {
match (&Some(5), &Some(6)) {
(Some(a), &Some(mut b)) => {
// Here, the `a` will be `&i32`, because in the first half of the tuple
// we hit a non-reference pattern and shift into `ref` mode.
//
// In the second half of the tuple there's no non-reference pattern,
// so `b` will be `i32` (bound with `move` mode). Moreover, `b` is
// mutable.
let _: &i32 = a;
b = 7;
let _: i32 = b;
},
_ => {},
};
}
fn nested_mixed_multiple_deref_1() {
let x = (1, &Some(5));
let y = &Some(x);
match y {
Some((a, Some(b))) => {
let _: &i32 = a;
let _: &i32 = b;
},
_ => {},
};
}
fn nested_mixed_multiple_deref_2() {
let x = &Some(5);
let y = &x;
match y {
Some(z) => {
let _: &i32 = z;
},
_ => {},
}
}
fn new_mutable_reference() {
let mut x = &mut Some(5);
match &mut x {
Some(y) => {
*y = 5;
},
None => { },
}
match &mut x {
Some(y) => {
println!("{}", *y);
},
None => {},
}
}
fn let_implicit_ref_binding() {
struct Foo(i32);
// Note that these rules apply to any pattern matching
// whether it be in a `match` or a `let`.
// For example, `x` here is a `ref` binding:
let Foo(x) = &Foo(3);
let _: &i32 = x;
}
fn explicit_mut_binding() {
match &Some(5i32) {
Some(mut n) => {
n += 1;
let _ = n;
}
None => {},
};
match &mut Some(5i32) {
Some(n) => {
*n += 1;
let _ = n;
}
None => {},
};
match &mut &mut Some(5i32) {
Some(n) => {
let _: &mut i32 = n;
}
None => {},
};
}
fn tuple_mut_and_mut_mut() {
match (Some(5i32), &Some(5i32)) {
(Some(n), Some(m)) => {
// `n` and `m` are bound as immutable references. Make new references from them to
// assert that.
let r = n;
let _ = r;
let q = m;
let _ = q;
// Assert the types. Note that we use `n` and `m` here which would fail had they been
// moved due to the assignments above.
let _: i32 = n;
let _: &i32 = m;
}
(_, _) => {},
};
match (&Some(5i32), &&Some(5i32)) {
(Some(n), Some(m)) => {
let _: &i32 = n;
let _: &i32 = m;
}
(_, _) => {},
};
match &mut &mut (Some(5i32), Some(5i32)) {
(Some(n), Some(m)) => {
// Dereferenced through &mut &mut, so a mutable binding results.
let _: &mut i32 = n;
let _: &mut i32 = m;
}
(_, _) => {},
};
match (&mut Some(5i32), &mut &mut Some(5i32)) {
(Some(n), Some(m)) => {
let _: &mut i32 = n;
let _: &mut i32 = m;
}
(_, _) => {},
};
}
fn min_mir_embedded_type() {
// The reduced invocation that an ICE was diagnosed with (was consuming
// adjustments in wrong order).
match (0u8, &&Some(5i32)) {
(_, Some(m)) => {
let _: &i32 = m;
}
(_, _) => {},
};
}
fn no_autoderef() {
// Binding.
let x = &3;
println!("{}", *x);
// Wildcard.
let _ = &3;
// Constant of generic type (string)
const Y: &'static str = "foo";
assert_eq!(0, match "foo" {
Y => 0,
_ => 1,
});
// Reference pattern.
let &x = &3;
}
pub fn main() {
let r: &Option<i32> = &Some(3);
let b = &4i32;
none_or_wildcard(r, b);
some_or_wildcard(r, b);
some_or_ref_none(r, b);
ref_some_or_none(r, b);
some_or_self(r);
multiple_deref(&&&&r);
match_with_or();
nested_mixed();
nested_mixed_multiple_deref_1();
nested_mixed_multiple_deref_2();
new_mutable_reference();
explicit_mut_binding();
tuple_mut_and_mut_mut();
min_mir_embedded_type();
let_implicit_ref_binding();
no_autoderef();
}

View file

@ -0,0 +1,44 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
fn with_u8() {
let s = 5u8;
let r = match &s {
4 => false,
5 => true,
_ => false,
};
assert!(r);
}
// A string literal isn't mistaken for a non-ref pattern (in which case we'd
// deref `s` and mess things up).
fn with_str() {
let s: &'static str = "abc";
match s {
"abc" => true,
_ => panic!(),
};
}
// Ditto with byte strings.
fn with_bytes() {
let s: &'static [u8] = b"abc";
match s {
b"abc" => true,
_ => panic!(),
};
}
pub fn main() {
with_str();
}

View file

@ -0,0 +1,20 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
pub fn main() {
let i = 5;
match &&&&i {
1 ... 3 => panic!(),
3 ... 8 => {},
_ => panic!(),
}
}

View file

@ -0,0 +1,27 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
fn foo<'a, 'b>(x: &'a &'b Option<u32>) -> &'a u32 {
let x: &'a &'a Option<u32> = x;
match x {
Some(r) => {
let _: &u32 = r;
r
},
&None => panic!(),
}
}
pub fn main() {
let x = Some(5);
foo(&&x);
}

View file

@ -0,0 +1,36 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(slice_patterns)]
#![feature(match_default_bindings)]
fn slice_pat() {
let sl: &[u8] = b"foo";
match sl {
[first, remainder..] => {
let _: &u8 = first;
assert_eq!(first, &b'f');
assert_eq!(remainder, b"oo");
}
[] => panic!(),
}
}
fn slice_pat_omission() {
match &[0, 1, 2] {
[..] => {}
};
}
fn main() {
slice_pat();
slice_pat_omission();
}

View file

@ -0,0 +1,33 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
#[derive(Debug, PartialEq)]
struct Foo {
x: u8,
}
pub fn main() {
let mut foo = Foo {
x: 1,
};
match &mut foo {
Foo{x: n} => {
*n += 1;
},
};
assert_eq!(foo, Foo{x: 2});
let Foo{x: n} = &foo;
assert_eq!(*n, 2);
}

View file

@ -0,0 +1,29 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
enum Foo {
Bar(Option<i8>, (), (), Vec<i32>),
Baz,
}
pub fn main() {
let foo = Foo::Bar(Some(1), (), (), vec![2, 3]);
match &foo {
Foo::Baz => panic!(),
Foo::Bar(None, ..) => panic!(),
Foo::Bar(Some(n), .., v) => {
assert_eq!((*v).len(), 2);
assert_eq!(*n, 1);
}
}
}

View file

@ -0,0 +1,23 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
pub fn main() {
let foo = (Some(1), (), (), vec![2, 3]);
match &foo {
(Some(n), .., v) => {
assert_eq!((*v).len(), 2);
assert_eq!(*n, 1);
}
(None, (), (), ..) => panic!(),
}
}

View file

@ -0,0 +1,20 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Encountered while testing #44614.
pub fn main() {
// Constant of generic type (int)
const X: &'static u32 = &22;
assert_eq!(0, match &22 {
X => 0,
_ => 1,
});
}

View file

@ -0,0 +1,14 @@
error[E0080]: constant evaluation error
--> $DIR/const-expr-addr-operator.rs:15:29
|
15 | const X: &'static u32 = &22;
| ^^^ unimplemented constant expression: address operator
|
note: for pattern here
--> $DIR/const-expr-addr-operator.rs:17:9
|
17 | X => 0,
| ^
error: aborting due to previous error

View file

@ -25,6 +25,8 @@ fn qux(foo: &Foo) {
fn zar(&foo: &Foo) {
}
// The somewhat unexpected help message in this case is courtesy of
// match_default_bindings.
fn agh(&&bar: &u32) {
}

View file

@ -9,27 +9,28 @@ error[E0308]: mismatched types
= help: did you mean `foo: &Foo`?
error[E0308]: mismatched types
--> $DIR/issue-38371.rs:28:9
--> $DIR/issue-38371.rs:30:9
|
28 | fn agh(&&bar: &u32) {
30 | fn agh(&&bar: &u32) {
| ^^^^ expected u32, found reference
|
= note: expected type `u32`
found type `&_`
= help: did you mean `bar: &u32`?
error[E0308]: mismatched types
--> $DIR/issue-38371.rs:31:8
--> $DIR/issue-38371.rs:33:8
|
31 | fn bgh(&&bar: u32) {
33 | fn bgh(&&bar: u32) {
| ^^^^^ expected u32, found reference
|
= note: expected type `u32`
found type `&_`
error[E0529]: expected an array or slice, found `u32`
--> $DIR/issue-38371.rs:34:9
--> $DIR/issue-38371.rs:36:9
|
34 | fn ugh(&[bar]: &u32) {
36 | fn ugh(&[bar]: &u32) {
| ^^^^^ pattern cannot match with input type `u32`
error: aborting due to 4 previous errors

View file

@ -0,0 +1,29 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// FIXME(tschottdorf): this test should pass.
#![feature(match_default_bindings)]
#[derive(PartialEq, Eq)]
struct Foo {
bar: i32,
}
const FOO: Foo = Foo{bar: 5};
fn main() {
let f = Foo{bar:6};
match &f {
FOO => {},
_ => panic!(),
}
}

View file

@ -0,0 +1,11 @@
error[E0308]: mismatched types
--> $DIR/const.rs:26:9
|
26 | FOO => {},
| ^^^ expected &Foo, found struct `Foo`
|
= note: expected type `&Foo`
found type `Foo`
error: aborting due to previous error

View file

@ -0,0 +1,34 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
enum Wrapper {
Wrap(i32),
}
use Wrapper::Wrap;
pub fn main() {
let Wrap(x) = &Wrap(3);
*x += 1;
if let Some(x) = &Some(3) {
*x += 1;
} else {
panic!();
}
while let Some(x) = &Some(3) {
*x += 1;
break;
}
}

View file

@ -0,0 +1,26 @@
error[E0594]: cannot assign to immutable borrowed content `*x`
--> $DIR/enum.rs:21:5
|
20 | let Wrap(x) = &Wrap(3);
| - consider changing this to `x`
21 | *x += 1;
| ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*x`
--> $DIR/enum.rs:25:9
|
24 | if let Some(x) = &Some(3) {
| - consider changing this to `x`
25 | *x += 1;
| ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*x`
--> $DIR/enum.rs:31:9
|
30 | while let Some(x) = &Some(3) {
| - consider changing this to `x`
31 | *x += 1;
| ^^^^^^^ cannot borrow as mutable
error: aborting due to 3 previous errors

View file

@ -0,0 +1,40 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
// Verify the binding mode shifts - only when no `&` are auto-dereferenced is the
// final default binding mode mutable.
fn main() {
match &&Some(5i32) {
Some(n) => {
*n += 1;
let _ = n;
}
None => {},
};
match &mut &Some(5i32) {
Some(n) => {
*n += 1;
let _ = n;
}
None => {},
};
match &&mut Some(5i32) {
Some(n) => {
*n += 1;
let _ = n;
}
None => {},
};
}

View file

@ -0,0 +1,26 @@
error[E0594]: cannot assign to immutable borrowed content `*n`
--> $DIR/explicit-mut.rs:19:13
|
18 | Some(n) => {
| - consider changing this to `n`
19 | *n += 1;
| ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*n`
--> $DIR/explicit-mut.rs:27:13
|
26 | Some(n) => {
| - consider changing this to `n`
27 | *n += 1;
| ^^^^^^^ cannot borrow as mutable
error[E0594]: cannot assign to immutable borrowed content `*n`
--> $DIR/explicit-mut.rs:35:13
|
34 | Some(n) => {
| - consider changing this to `n`
35 | *n += 1;
| ^^^^^^^ cannot borrow as mutable
error: aborting due to 3 previous errors

View file

@ -0,0 +1,20 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
struct Foo {}
pub fn main() {
let mut tups = vec![(Foo{}, Foo{})];
// The below desugars to &(ref n, mut m).
for (n, mut m) in &tups {
}
}

View file

@ -0,0 +1,10 @@
error[E0009]: cannot bind by-move and by-ref in the same pattern
--> $DIR/for.rs:18:13
|
18 | for (n, mut m) in &tups {
| - ^^^^^ by-move pattern here
| |
| both by-ref and by-move used
error: aborting due to previous error

View file

@ -0,0 +1,21 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
// FIXME(tschottdorf): This should compile. See #44912.
pub fn main() {
let x = &Some((3, 3));
let _: &i32 = match x {
Some((x, 3)) | &Some((ref x, 5)) => x,
_ => &5i32,
};
}

View file

@ -0,0 +1,8 @@
error[E0409]: variable `x` is bound in inconsistent ways within the same match arm
--> $DIR/issue-44912-or.rs:18:35
|
18 | Some((x, 3)) | &Some((ref x, 5)) => x,
| - first binding ^ bound in different ways
error: aborting due to previous error

View file

@ -0,0 +1,36 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(match_default_bindings)]
// FIXME(tschottdorf): we want these to compile, but they don't.
fn with_str() {
let s: &'static str = "abc";
match &s {
"abc" => true,
_ => panic!(),
};
}
fn with_bytes() {
let s: &'static [u8] = b"abc";
match &s {
b"abc" => true,
_ => panic!(),
};
}
pub fn main() {
with_str();
with_bytes();
}

View file

@ -0,0 +1,20 @@
error[E0308]: mismatched types
--> $DIR/lit.rs:19:13
|
19 | "abc" => true,
| ^^^^^ expected &str, found str
|
= note: expected type `&&str`
found type `&'static str`
error[E0308]: mismatched types
--> $DIR/lit.rs:28:9
|
28 | b"abc" => true,
| ^^^^^^ expected &[u8], found array of 3 elements
|
= note: expected type `&&[u8]`
found type `&'static [u8; 3]`
error: aborting due to 2 previous errors

View file

@ -0,0 +1,21 @@
// Copyright 2017 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Without caching type lookups in FnCtxt.resolve_ty_and_def_ufcs
// the error below would be reported twice (once when checking
// for a non-ref pattern, once when processing the pattern).
fn main() {
let foo = 22;
match foo {
u32::XXX => { }
_ => { }
}
}

View file

@ -0,0 +1,8 @@
error[E0599]: no associated item named `XXX` found for type `u32` in the current scope
--> $DIR/no-double-error.rs:18:9
|
18 | u32::XXX => { }
| ^^^^^^^^
error: aborting due to previous error

View file

@ -0,0 +1,20 @@
// Copyright 2016 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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(slice_patterns)]
#![feature(match_default_bindings)]
pub fn main() {
let sl: &[u8] = b"foo";
match sl {
[first, remainder..] => {},
};
}

View file

@ -0,0 +1,8 @@
error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/slice.rs:17:11
|
17 | match sl {
| ^^ pattern `&[]` not covered
error: aborting due to previous error