Add feature gate
This commit is contained in:
parent
b2cb42d6a7
commit
0537d301c5
8 changed files with 69 additions and 45 deletions
|
@ -376,6 +376,8 @@ declare_features! (
|
||||||
(active, deprecated_safe, "1.61.0", Some(94978), None),
|
(active, deprecated_safe, "1.61.0", Some(94978), None),
|
||||||
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
|
/// Allows having using `suggestion` in the `#[deprecated]` attribute.
|
||||||
(active, deprecated_suggestion, "1.61.0", Some(94785), None),
|
(active, deprecated_suggestion, "1.61.0", Some(94785), None),
|
||||||
|
/// Allows patterns to dereference values to match them.
|
||||||
|
(active, deref_patterns, "1.64.0", Some(87121), None),
|
||||||
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
|
/// Tells rustdoc to automatically generate `#[doc(cfg(...))]`.
|
||||||
(active, doc_auto_cfg, "1.58.0", Some(43781), None),
|
(active, doc_auto_cfg, "1.58.0", Some(43781), None),
|
||||||
/// Allows `#[doc(cfg(...))]`.
|
/// Allows `#[doc(cfg(...))]`.
|
||||||
|
|
|
@ -401,7 +401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
|
if self.tcx.features().deref_patterns && let hir::ExprKind::Lit(Spanned { node: ast::LitKind::Str(..), .. }) = lt.kind {
|
||||||
let tcx = self.tcx;
|
let tcx = self.tcx;
|
||||||
let expected = self.resolve_vars_if_possible(expected);
|
let expected = self.resolve_vars_if_possible(expected);
|
||||||
pat_ty = match expected.kind() {
|
pat_ty = match expected.kind() {
|
||||||
|
|
|
@ -597,6 +597,7 @@ symbols! {
|
||||||
deref,
|
deref,
|
||||||
deref_method,
|
deref_method,
|
||||||
deref_mut,
|
deref_mut,
|
||||||
|
deref_patterns,
|
||||||
deref_target,
|
deref_target,
|
||||||
derive,
|
derive,
|
||||||
derive_const,
|
derive_const,
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
// check-run-results
|
// check-run-results
|
||||||
|
#![feature(deref_patterns)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test(Some(String::from("42")));
|
test(Some(String::from("42")));
|
||||||
|
@ -13,4 +14,4 @@ fn test(o: Option<String>) {
|
||||||
Some(_) => println!("something else?"),
|
Some(_) => println!("something else?"),
|
||||||
None => println!("nil"),
|
None => println!("nil"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
7
src/test/ui/deref-patterns/gate.rs
Normal file
7
src/test/ui/deref-patterns/gate.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// gate-test-deref_patterns
|
||||||
|
fn main() {
|
||||||
|
match String::new() {
|
||||||
|
"" | _ => {}
|
||||||
|
//~^ mismatched types
|
||||||
|
}
|
||||||
|
}
|
11
src/test/ui/deref-patterns/gate.stderr
Normal file
11
src/test/ui/deref-patterns/gate.stderr
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/gate.rs:3:9
|
||||||
|
|
|
||||||
|
LL | match String::new() {
|
||||||
|
| ------------- this expression has type `String`
|
||||||
|
LL | "" | _ => {}
|
||||||
|
| ^^ expected struct `String`, found `&str`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
|
@ -1,5 +1,7 @@
|
||||||
// compile-flags: -Z unpretty=mir
|
// compile-flags: -Z unpretty=mir
|
||||||
// build-pass
|
// build-pass
|
||||||
|
#![feature(deref_patterns)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let s = Some(String::new());
|
let s = Some(String::new());
|
||||||
let a;
|
let a;
|
||||||
|
@ -7,4 +9,4 @@ fn main() {
|
||||||
Some("a") => a = 1234,
|
Some("a") => a = 1234,
|
||||||
s => a = 4321,
|
s => a = 4321,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,99 +1,99 @@
|
||||||
// WARNING: This output format is intended for human consumers only
|
// WARNING: This output format is intended for human consumers only
|
||||||
// and is subject to change without notice. Knock yourself out.
|
// and is subject to change without notice. Knock yourself out.
|
||||||
fn main() -> () {
|
fn main() -> () {
|
||||||
let mut _0: (); // return place in scope 0 at $DIR/mir.rs:3:11: 3:11
|
let mut _0: (); // return place in scope 0 at $DIR/mir.rs:5:11: 5:11
|
||||||
let _1: std::option::Option<std::string::String>; // in scope 0 at $DIR/mir.rs:4:9: 4:10
|
let _1: std::option::Option<std::string::String>; // in scope 0 at $DIR/mir.rs:6:9: 6:10
|
||||||
let mut _2: std::string::String; // in scope 0 at $DIR/mir.rs:4:18: 4:31
|
let mut _2: std::string::String; // in scope 0 at $DIR/mir.rs:6:18: 6:31
|
||||||
let mut _4: &std::string::String; // in scope 0 at $DIR/mir.rs:7:14: 7:17
|
let mut _4: &std::string::String; // in scope 0 at $DIR/mir.rs:9:14: 9:17
|
||||||
let mut _5: &str; // in scope 0 at $DIR/mir.rs:7:14: 7:17
|
let mut _5: &str; // in scope 0 at $DIR/mir.rs:9:14: 9:17
|
||||||
let mut _6: bool; // in scope 0 at $DIR/mir.rs:7:14: 7:17
|
let mut _6: bool; // in scope 0 at $DIR/mir.rs:9:14: 9:17
|
||||||
let mut _7: isize; // in scope 0 at $DIR/mir.rs:7:9: 7:18
|
let mut _7: isize; // in scope 0 at $DIR/mir.rs:9:9: 9:18
|
||||||
let mut _9: bool; // in scope 0 at $DIR/mir.rs:10:1: 10:2
|
let mut _9: bool; // in scope 0 at $DIR/mir.rs:12:1: 12:2
|
||||||
scope 1 {
|
scope 1 {
|
||||||
debug s => _1; // in scope 1 at $DIR/mir.rs:4:9: 4:10
|
debug s => _1; // in scope 1 at $DIR/mir.rs:6:9: 6:10
|
||||||
let _3: i32; // in scope 1 at $DIR/mir.rs:5:9: 5:10
|
let _3: i32; // in scope 1 at $DIR/mir.rs:7:9: 7:10
|
||||||
scope 2 {
|
scope 2 {
|
||||||
debug a => _3; // in scope 2 at $DIR/mir.rs:5:9: 5:10
|
debug a => _3; // in scope 2 at $DIR/mir.rs:7:9: 7:10
|
||||||
let _8: std::option::Option<std::string::String>; // in scope 2 at $DIR/mir.rs:8:9: 8:10
|
let _8: std::option::Option<std::string::String>; // in scope 2 at $DIR/mir.rs:10:9: 10:10
|
||||||
scope 3 {
|
scope 3 {
|
||||||
debug s => _8; // in scope 3 at $DIR/mir.rs:8:9: 8:10
|
debug s => _8; // in scope 3 at $DIR/mir.rs:10:9: 10:10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bb0: {
|
bb0: {
|
||||||
_9 = const false; // scope 0 at $DIR/mir.rs:4:9: 4:10
|
_9 = const false; // scope 0 at $DIR/mir.rs:6:9: 6:10
|
||||||
_2 = String::new() -> bb1; // scope 0 at $DIR/mir.rs:4:18: 4:31
|
_2 = String::new() -> bb1; // scope 0 at $DIR/mir.rs:6:18: 6:31
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/mir.rs:4:18: 4:29
|
// + span: $DIR/mir.rs:6:18: 6:29
|
||||||
// + literal: Const { ty: fn() -> String {String::new}, val: Value(Scalar(<ZST>)) }
|
// + literal: Const { ty: fn() -> String {String::new}, val: Value(Scalar(<ZST>)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
bb1: {
|
bb1: {
|
||||||
_9 = const true; // scope 0 at $DIR/mir.rs:4:13: 4:32
|
_9 = const true; // scope 0 at $DIR/mir.rs:6:13: 6:32
|
||||||
Deinit(_1); // scope 0 at $DIR/mir.rs:4:13: 4:32
|
Deinit(_1); // scope 0 at $DIR/mir.rs:6:13: 6:32
|
||||||
((_1 as Some).0: std::string::String) = move _2; // scope 0 at $DIR/mir.rs:4:13: 4:32
|
((_1 as Some).0: std::string::String) = move _2; // scope 0 at $DIR/mir.rs:6:13: 6:32
|
||||||
discriminant(_1) = 1; // scope 0 at $DIR/mir.rs:4:13: 4:32
|
discriminant(_1) = 1; // scope 0 at $DIR/mir.rs:6:13: 6:32
|
||||||
_7 = discriminant(_1); // scope 2 at $DIR/mir.rs:6:11: 6:12
|
_7 = discriminant(_1); // scope 2 at $DIR/mir.rs:8:11: 8:12
|
||||||
switchInt(move _7) -> [1_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/mir.rs:6:5: 6:12
|
switchInt(move _7) -> [1_isize: bb3, otherwise: bb2]; // scope 2 at $DIR/mir.rs:8:5: 8:12
|
||||||
}
|
}
|
||||||
|
|
||||||
bb2: {
|
bb2: {
|
||||||
_9 = const false; // scope 2 at $DIR/mir.rs:8:9: 8:10
|
_9 = const false; // scope 2 at $DIR/mir.rs:10:9: 10:10
|
||||||
_8 = move _1; // scope 2 at $DIR/mir.rs:8:9: 8:10
|
_8 = move _1; // scope 2 at $DIR/mir.rs:10:9: 10:10
|
||||||
_3 = const 4321_i32; // scope 3 at $DIR/mir.rs:8:14: 8:22
|
_3 = const 4321_i32; // scope 3 at $DIR/mir.rs:10:14: 10:22
|
||||||
drop(_8) -> [return: bb7, unwind: bb12]; // scope 2 at $DIR/mir.rs:8:21: 8:22
|
drop(_8) -> [return: bb7, unwind: bb12]; // scope 2 at $DIR/mir.rs:10:21: 10:22
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3: {
|
bb3: {
|
||||||
_4 = &((_1 as Some).0: std::string::String); // scope 2 at $DIR/mir.rs:7:14: 7:17
|
_4 = &((_1 as Some).0: std::string::String); // scope 2 at $DIR/mir.rs:9:14: 9:17
|
||||||
_5 = <String as Deref>::deref(move _4) -> bb4; // scope 2 at $DIR/mir.rs:7:14: 7:17
|
_5 = <String as Deref>::deref(move _4) -> bb4; // scope 2 at $DIR/mir.rs:9:14: 9:17
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/mir.rs:7:14: 7:17
|
// + span: $DIR/mir.rs:9:14: 9:17
|
||||||
// + literal: Const { ty: for<'r> fn(&'r String) -> &'r <String as Deref>::Target {<String as Deref>::deref}, val: Value(Scalar(<ZST>)) }
|
// + literal: Const { ty: for<'r> fn(&'r String) -> &'r <String as Deref>::Target {<String as Deref>::deref}, val: Value(Scalar(<ZST>)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
bb4: {
|
bb4: {
|
||||||
_6 = <str as PartialEq>::eq(_5, const "a") -> [return: bb5, unwind: bb12]; // scope 2 at $DIR/mir.rs:7:14: 7:17
|
_6 = <str as PartialEq>::eq(_5, const "a") -> [return: bb5, unwind: bb12]; // scope 2 at $DIR/mir.rs:9:14: 9:17
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/mir.rs:7:14: 7:17
|
// + span: $DIR/mir.rs:9:14: 9:17
|
||||||
// + literal: Const { ty: for<'r, 's> fn(&'r str, &'s str) -> bool {<str as PartialEq>::eq}, val: Value(Scalar(<ZST>)) }
|
// + literal: Const { ty: for<'r, 's> fn(&'r str, &'s str) -> bool {<str as PartialEq>::eq}, val: Value(Scalar(<ZST>)) }
|
||||||
// mir::Constant
|
// mir::Constant
|
||||||
// + span: $DIR/mir.rs:7:14: 7:17
|
// + span: $DIR/mir.rs:9:14: 9:17
|
||||||
// + literal: Const { ty: &str, val: Value(Slice(..)) }
|
// + literal: Const { ty: &str, val: Value(Slice(..)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
bb5: {
|
bb5: {
|
||||||
switchInt(move _6) -> [false: bb2, otherwise: bb6]; // scope 2 at $DIR/mir.rs:7:14: 7:17
|
switchInt(move _6) -> [false: bb2, otherwise: bb6]; // scope 2 at $DIR/mir.rs:9:14: 9:17
|
||||||
}
|
}
|
||||||
|
|
||||||
bb6: {
|
bb6: {
|
||||||
_3 = const 1234_i32; // scope 2 at $DIR/mir.rs:7:22: 7:30
|
_3 = const 1234_i32; // scope 2 at $DIR/mir.rs:9:22: 9:30
|
||||||
goto -> bb7; // scope 2 at $DIR/mir.rs:7:22: 7:30
|
goto -> bb7; // scope 2 at $DIR/mir.rs:9:22: 9:30
|
||||||
}
|
}
|
||||||
|
|
||||||
bb7: {
|
bb7: {
|
||||||
switchInt(_9) -> [false: bb8, otherwise: bb10]; // scope 0 at $DIR/mir.rs:10:1: 10:2
|
switchInt(_9) -> [false: bb8, otherwise: bb10]; // scope 0 at $DIR/mir.rs:12:1: 12:2
|
||||||
}
|
}
|
||||||
|
|
||||||
bb8: {
|
bb8: {
|
||||||
_9 = const false; // scope 0 at $DIR/mir.rs:10:1: 10:2
|
_9 = const false; // scope 0 at $DIR/mir.rs:12:1: 12:2
|
||||||
return; // scope 0 at $DIR/mir.rs:10:2: 10:2
|
return; // scope 0 at $DIR/mir.rs:12:2: 12:2
|
||||||
}
|
}
|
||||||
|
|
||||||
bb9 (cleanup): {
|
bb9 (cleanup): {
|
||||||
resume; // scope 0 at $DIR/mir.rs:3:1: 10:2
|
resume; // scope 0 at $DIR/mir.rs:5:1: 12:2
|
||||||
}
|
}
|
||||||
|
|
||||||
bb10: {
|
bb10: {
|
||||||
drop(_1) -> bb8; // scope 0 at $DIR/mir.rs:10:1: 10:2
|
drop(_1) -> bb8; // scope 0 at $DIR/mir.rs:12:1: 12:2
|
||||||
}
|
}
|
||||||
|
|
||||||
bb11 (cleanup): {
|
bb11 (cleanup): {
|
||||||
drop(_1) -> bb9; // scope 0 at $DIR/mir.rs:10:1: 10:2
|
drop(_1) -> bb9; // scope 0 at $DIR/mir.rs:12:1: 12:2
|
||||||
}
|
}
|
||||||
|
|
||||||
bb12 (cleanup): {
|
bb12 (cleanup): {
|
||||||
switchInt(_9) -> [false: bb9, otherwise: bb11]; // scope 0 at $DIR/mir.rs:10:1: 10:2
|
switchInt(_9) -> [false: bb9, otherwise: bb11]; // scope 0 at $DIR/mir.rs:12:1: 12:2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue