mirror of https://github.com/rust-lang/rust.git
55 lines
2.1 KiB
Rust
55 lines
2.1 KiB
Rust
//@ revisions: stable deref_patterns
|
|
//@[deref_patterns] check-pass
|
|
//! `deref_patterns` allows string and byte string literal patterns to implicitly peel references
|
|
//! and smart pointers from the scrutinee before matching. Since strings and byte strings themselves
|
|
//! have reference types, we need to make sure we don't peel too much. By leaving the type of the
|
|
//! match scrutinee partially uninferred, these tests make sure we only peel as much as needed in
|
|
//! order to match. In particular, when peeling isn't needed, the results should be the same was
|
|
//! we'd get without `deref_patterns` enabled.
|
|
|
|
#![cfg_attr(deref_patterns, feature(deref_patterns))]
|
|
#![cfg_attr(deref_patterns, expect(incomplete_features))]
|
|
|
|
fn uninferred<T>() -> T { unimplemented!() }
|
|
|
|
// Assert type equality without allowing coercions.
|
|
trait Is<T> {}
|
|
impl<T> Is<T> for T {}
|
|
fn has_type<T>(_: impl Is<T>) {}
|
|
|
|
fn main() {
|
|
// We don't need to peel anything to unify the type of `x` with `&str`, so `x: &str`.
|
|
let x = uninferred();
|
|
if let "..." = x {}
|
|
has_type::<&str>(x);
|
|
|
|
// We don't need to peel anything to unify the type of `&x` with `&[u8; 3]`, so `x: [u8; 3]`.
|
|
let x = uninferred();
|
|
if let b"..." = &x {}
|
|
has_type::<[u8; 3]>(x);
|
|
|
|
// Peeling a single `&` lets us unify the type of `&x` with `&[u8; 3]`, giving `x: [u8; 3]`.
|
|
let x = uninferred();
|
|
if let b"..." = &&x {}
|
|
//[stable]~^ ERROR: mismatched types
|
|
has_type::<[u8; 3]>(x);
|
|
|
|
// We have to peel both the `&` and the box before unifying the type of `x` with `&str`.
|
|
let x = uninferred();
|
|
if let "..." = &Box::new(x) {}
|
|
//[stable]~^ ERROR mismatched types
|
|
has_type::<&str>(x);
|
|
|
|
// After peeling the box, we can unify the type of `&x` with `&[u8; 3]`, giving `x: [u8; 3]`.
|
|
let x = uninferred();
|
|
if let b"..." = Box::new(&x) {}
|
|
//[stable]~^ ERROR mismatched types
|
|
has_type::<[u8; 3]>(x);
|
|
|
|
// `&` and `&mut` aren't interchangeable: `&mut`s need to be peeled before unifying, like boxes:
|
|
let mut x = uninferred();
|
|
if let "..." = &mut x {}
|
|
//[stable]~^ ERROR mismatched types
|
|
has_type::<&str>(x);
|
|
}
|