forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This handles using deref patterns to choose the correct match arm. This does not handle bindings or guards. Co-authored-by: Deadbeef <[email protected]>
- Loading branch information
Showing
11 changed files
with
259 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
//@ run-pass | ||
#![feature(deref_patterns)] | ||
#![allow(incomplete_features)] | ||
|
||
fn simple_vec(vec: Vec<u32>) -> u32 { | ||
match vec { | ||
deref!([]) => 100, | ||
// FIXME(deref_patterns): fake borrows break guards | ||
// deref!([x]) if x == 4 => x + 4, | ||
deref!([x]) => x, | ||
deref!([1, x]) => x + 200, | ||
deref!(ref slice) => slice.iter().sum(), | ||
_ => 2000, | ||
} | ||
} | ||
|
||
fn nested_vec(vecvec: Vec<Vec<u32>>) -> u32 { | ||
match vecvec { | ||
deref!([]) => 0, | ||
deref!([deref!([x])]) => x, | ||
deref!([deref!([0, x]) | deref!([1, x])]) => x, | ||
deref!([ref x]) => x.iter().sum(), | ||
deref!([deref!([]), deref!([1, x, y])]) => y - x, | ||
_ => 2000, | ||
} | ||
} | ||
|
||
fn main() { | ||
assert_eq!(simple_vec(vec![1]), 1); | ||
assert_eq!(simple_vec(vec![1, 2]), 202); | ||
assert_eq!(simple_vec(vec![1, 2, 3]), 6); | ||
|
||
assert_eq!(nested_vec(vec![vec![0, 42]]), 42); | ||
assert_eq!(nested_vec(vec![vec![1, 42]]), 42); | ||
assert_eq!(nested_vec(vec![vec![1, 2, 3]]), 6); | ||
assert_eq!(nested_vec(vec![vec![], vec![1, 2, 3]]), 1); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
//@ run-pass | ||
// Test the execution of deref patterns. | ||
#![feature(deref_patterns)] | ||
#![allow(incomplete_features)] | ||
|
||
fn branch(vec: Vec<u32>) -> u32 { | ||
match vec { | ||
deref!([]) => 0, | ||
deref!([1, _, 3]) => 1, | ||
deref!([2, ..]) => 2, | ||
_ => 1000, | ||
} | ||
} | ||
|
||
fn nested(vec: Vec<Vec<u32>>) -> u32 { | ||
match vec { | ||
deref!([deref!([]), ..]) => 1, | ||
deref!([deref!([0, ..]), deref!([1, ..])]) => 2, | ||
_ => 1000, | ||
} | ||
} | ||
|
||
fn main() { | ||
assert!(matches!(Vec::<u32>::new(), deref!([]))); | ||
assert!(matches!(vec![1], deref!([1]))); | ||
assert!(matches!(&vec![1], deref!([1]))); | ||
assert!(matches!(vec![&1], deref!([1]))); | ||
assert!(matches!(vec![vec![1]], deref!([deref!([1])]))); | ||
|
||
assert_eq!(branch(vec![]), 0); | ||
assert_eq!(branch(vec![1, 2, 3]), 1); | ||
assert_eq!(branch(vec![3, 2, 1]), 1000); | ||
assert_eq!(branch(vec![2]), 2); | ||
assert_eq!(branch(vec![2, 3]), 2); | ||
assert_eq!(branch(vec![3, 2]), 1000); | ||
|
||
assert_eq!(nested(vec![vec![], vec![2]]), 1); | ||
assert_eq!(nested(vec![vec![0], vec![1]]), 2); | ||
assert_eq!(nested(vec![vec![0, 2], vec![1, 2]]), 2); | ||
} |
24 changes: 24 additions & 0 deletions
24
tests/ui/pattern/deref-patterns/cant_move_out_of_pattern.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#![feature(deref_patterns)] | ||
#![allow(incomplete_features)] | ||
|
||
use std::rc::Rc; | ||
|
||
struct Struct; | ||
|
||
fn cant_move_out_box(b: Box<Struct>) -> Struct { | ||
match b { | ||
//~^ ERROR: cannot move out of a shared reference | ||
deref!(x) => x, | ||
_ => unreachable!(), | ||
} | ||
} | ||
|
||
fn cant_move_out_rc(rc: Rc<Struct>) -> Struct { | ||
match rc { | ||
//~^ ERROR: cannot move out of a shared reference | ||
deref!(x) => x, | ||
_ => unreachable!(), | ||
} | ||
} | ||
|
||
fn main() {} |
27 changes: 27 additions & 0 deletions
27
tests/ui/pattern/deref-patterns/cant_move_out_of_pattern.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
error[E0507]: cannot move out of a shared reference | ||
--> $DIR/cant_move_out_of_pattern.rs:9:11 | ||
| | ||
LL | match b { | ||
| ^ | ||
LL | | ||
LL | deref!(x) => x, | ||
| - | ||
| | | ||
| data moved here | ||
| move occurs because `x` has type `Struct`, which does not implement the `Copy` trait | ||
|
||
error[E0507]: cannot move out of a shared reference | ||
--> $DIR/cant_move_out_of_pattern.rs:17:11 | ||
| | ||
LL | match rc { | ||
| ^^ | ||
LL | | ||
LL | deref!(x) => x, | ||
| - | ||
| | | ||
| data moved here | ||
| move occurs because `x` has type `Struct`, which does not implement the `Copy` trait | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0507`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#![feature(deref_patterns)] | ||
#![allow(incomplete_features)] | ||
|
||
fn main() { | ||
// FIXME(deref_patterns): fails to typecheck because `"foo"` has type &str but deref creates a | ||
// place of type `str`. | ||
match "foo".to_string() { | ||
deref!("foo") => {} | ||
//~^ ERROR: mismatched types | ||
_ => {} | ||
} | ||
match &"foo".to_string() { | ||
deref!("foo") => {} | ||
//~^ ERROR: mismatched types | ||
_ => {} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
error[E0308]: mismatched types | ||
--> $DIR/typeck_fail.rs:8:16 | ||
| | ||
LL | match "foo".to_string() { | ||
| ----------------- this expression has type `String` | ||
LL | deref!("foo") => {} | ||
| ^^^^^ expected `str`, found `&str` | ||
|
||
error[E0308]: mismatched types | ||
--> $DIR/typeck_fail.rs:13:16 | ||
| | ||
LL | match &"foo".to_string() { | ||
| ------------------ this expression has type `&String` | ||
LL | deref!("foo") => {} | ||
| ^^^^^ expected `str`, found `&str` | ||
|
||
error: aborting due to 2 previous errors | ||
|
||
For more information about this error, try `rustc --explain E0308`. |