Remove feature(string_deref_patterns)
This commit is contained in:
parent
0e89999425
commit
ef8d943ecd
17 changed files with 24 additions and 150 deletions
|
|
@ -271,6 +271,8 @@ declare_features! (
|
|||
/// Allows `#[link(kind = "static-nobundle", ...)]`.
|
||||
(removed, static_nobundle, "1.63.0", Some(37403),
|
||||
Some(r#"subsumed by `#[link(kind = "static", modifiers = "-bundle", ...)]`"#), 95818),
|
||||
/// Allows string patterns to dereference values to match them.
|
||||
(removed, string_deref_patterns, "CURRENT_RUSTC_VERSION", Some(87121), Some("superseded by `deref_patterns`"), 150530),
|
||||
(removed, struct_inherit, "1.0.0", None, None),
|
||||
(removed, test_removed_feature, "1.0.0", None, None),
|
||||
/// Allows using items which are missing stability attributes
|
||||
|
|
|
|||
|
|
@ -647,8 +647,6 @@ declare_features! (
|
|||
(unstable, stmt_expr_attributes, "1.6.0", Some(15701)),
|
||||
/// Allows lints part of the strict provenance effort.
|
||||
(unstable, strict_provenance_lints, "1.61.0", Some(130351)),
|
||||
/// Allows string patterns to dereference values to match them.
|
||||
(unstable, string_deref_patterns, "1.67.0", Some(87121)),
|
||||
/// Allows `super let` statements.
|
||||
(unstable, super_let, "1.88.0", Some(139076)),
|
||||
/// Allows subtrait items to shadow supertrait items.
|
||||
|
|
|
|||
|
|
@ -996,20 +996,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
pat_ty = self.tcx.types.str_;
|
||||
}
|
||||
|
||||
if self.tcx.features().string_deref_patterns()
|
||||
&& let hir::PatExprKind::Lit {
|
||||
lit: Spanned { node: ast::LitKind::Str(..), .. }, ..
|
||||
} = lt.kind
|
||||
{
|
||||
let tcx = self.tcx;
|
||||
let expected = self.resolve_vars_if_possible(expected);
|
||||
pat_ty = match expected.kind() {
|
||||
ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => expected,
|
||||
ty::Str => Ty::new_static_str(tcx),
|
||||
_ => pat_ty,
|
||||
};
|
||||
}
|
||||
|
||||
// Somewhat surprising: in this case, the subtyping relation goes the
|
||||
// opposite way as the other cases. Actually what we really want is not
|
||||
// a subtyping relation at all but rather that there exists a LUB
|
||||
|
|
|
|||
|
|
@ -827,7 +827,6 @@ pub enum PatKind<'tcx> {
|
|||
/// much simpler.
|
||||
/// * raw pointers derived from integers, other raw pointers will have already resulted in an
|
||||
/// error.
|
||||
/// * `String`, if `string_deref_patterns` is enabled.
|
||||
Constant {
|
||||
value: ty::Value<'tcx>,
|
||||
},
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
let mut expect = self.literal_operand(test.span, Const::from_ty_value(tcx, value));
|
||||
|
||||
let mut place = place;
|
||||
let mut block = block;
|
||||
|
||||
match cast_ty.kind() {
|
||||
ty::Str => {
|
||||
// String literal patterns may have type `str` if `deref_patterns` is
|
||||
|
|
@ -175,34 +175,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
place = ref_place;
|
||||
cast_ty = ref_str_ty;
|
||||
}
|
||||
ty::Adt(def, _) if tcx.is_lang_item(def.did(), LangItem::String) => {
|
||||
if !tcx.features().string_deref_patterns() {
|
||||
span_bug!(
|
||||
test.span,
|
||||
"matching on `String` went through without enabling string_deref_patterns"
|
||||
);
|
||||
}
|
||||
let re_erased = tcx.lifetimes.re_erased;
|
||||
let ref_str_ty = Ty::new_imm_ref(tcx, re_erased, tcx.types.str_);
|
||||
let ref_str = self.temp(ref_str_ty, test.span);
|
||||
let eq_block = self.cfg.start_new_block();
|
||||
// `let ref_str: &str = <String as Deref>::deref(&place);`
|
||||
self.call_deref(
|
||||
block,
|
||||
eq_block,
|
||||
place,
|
||||
Mutability::Not,
|
||||
cast_ty,
|
||||
ref_str,
|
||||
test.span,
|
||||
);
|
||||
// Since we generated a `ref_str = <String as Deref>::deref(&place) -> eq_block` terminator,
|
||||
// we need to add all further statements to `eq_block`.
|
||||
// Similarly, the normal test code should be generated for the `&str`, instead of the `String`.
|
||||
block = eq_block;
|
||||
place = ref_str;
|
||||
cast_ty = ref_str_ty;
|
||||
}
|
||||
&ty::Pat(base, _) => {
|
||||
assert_eq!(cast_ty, value.ty);
|
||||
assert!(base.is_trivially_pure_clone_copy());
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc_abi::{FieldIdx, Integer};
|
|||
use rustc_errors::codes::*;
|
||||
use rustc_hir::def::{CtorOf, DefKind, Res};
|
||||
use rustc_hir::pat_util::EnumerateAndAdjustIterator;
|
||||
use rustc_hir::{self as hir, LangItem, RangeEnd};
|
||||
use rustc_hir::{self as hir, RangeEnd};
|
||||
use rustc_index::Idx;
|
||||
use rustc_middle::mir::interpret::LitToConstInput;
|
||||
use rustc_middle::thir::{
|
||||
|
|
@ -626,23 +626,7 @@ impl<'tcx> PatCtxt<'tcx> {
|
|||
// the pattern's type will be `&[u8]` whereas the literal's type is `&[u8; 3]`; using the
|
||||
// pattern's type means we'll properly translate it to a slice reference pattern. This works
|
||||
// because slices and arrays have the same valtree representation.
|
||||
// HACK: As an exception, use the literal's type if `pat_ty` is `String`; this can happen if
|
||||
// `string_deref_patterns` is enabled. There's a special case for that when lowering to MIR.
|
||||
// FIXME(deref_patterns): This hack won't be necessary once `string_deref_patterns` is
|
||||
// superseded by a more general implementation of deref patterns.
|
||||
let ct_ty = match pat_ty {
|
||||
Some(pat_ty)
|
||||
if let ty::Adt(def, _) = *pat_ty.kind()
|
||||
&& self.tcx.is_lang_item(def.did(), LangItem::String) =>
|
||||
{
|
||||
if !self.tcx.features().string_deref_patterns() {
|
||||
span_bug!(
|
||||
expr.span,
|
||||
"matching on `String` went through without enabling string_deref_patterns"
|
||||
);
|
||||
}
|
||||
self.typeck_results.node_type(expr.hir_id)
|
||||
}
|
||||
Some(pat_ty) => pat_ty,
|
||||
None => self.typeck_results.node_type(expr.hir_id),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ The tracking issue for this feature is: [#87121]
|
|||
------------------------
|
||||
|
||||
> **Note**: This feature is incomplete. In the future, it is meant to supersede
|
||||
> [`box_patterns`] and [`string_deref_patterns`].
|
||||
> [`box_patterns`].
|
||||
|
||||
This feature permits pattern matching on [smart pointers in the standard library] through their
|
||||
`Deref` target types, either implicitly or with explicit `deref!(_)` patterns (the syntax of which
|
||||
|
|
@ -103,5 +103,4 @@ match *(b"test" as &[u8]) {
|
|||
```
|
||||
|
||||
[`box_patterns`]: ./box-patterns.md
|
||||
[`string_deref_patterns`]: ./string-deref-patterns.md
|
||||
[smart pointers in the standard library]: https://doc.rust-lang.org/std/ops/trait.DerefPure.html#implementors
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
# `string_deref_patterns`
|
||||
|
||||
The tracking issue for this feature is: [#87121]
|
||||
|
||||
[#87121]: https://github.com/rust-lang/rust/issues/87121
|
||||
|
||||
------------------------
|
||||
|
||||
> **Note**: This feature will be superseded by [`deref_patterns`] in the future.
|
||||
|
||||
This feature permits pattern matching `String` to `&str` through [its `Deref` implementation].
|
||||
|
||||
```rust
|
||||
#![feature(string_deref_patterns)]
|
||||
|
||||
pub enum Value {
|
||||
String(String),
|
||||
Number(u32),
|
||||
}
|
||||
|
||||
pub fn is_it_the_answer(value: Value) -> bool {
|
||||
match value {
|
||||
Value::String("42") => true,
|
||||
Value::Number(42) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Without this feature other constructs such as match guards have to be used.
|
||||
|
||||
```rust
|
||||
# pub enum Value {
|
||||
# String(String),
|
||||
# Number(u32),
|
||||
# }
|
||||
#
|
||||
pub fn is_it_the_answer(value: Value) -> bool {
|
||||
match value {
|
||||
Value::String(s) if s == "42" => true,
|
||||
Value::Number(42) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[`deref_patterns`]: ./deref-patterns.md
|
||||
[its `Deref` implementation]: https://doc.rust-lang.org/std/string/struct.String.html#impl-Deref-for-String
|
||||
|
|
@ -7,10 +7,11 @@ fn foo(_1: Option<String>) -> i32 {
|
|||
let mut _3: isize;
|
||||
let mut _4: &std::string::String;
|
||||
let mut _5: &str;
|
||||
let mut _6: bool;
|
||||
let _7: std::option::Option<std::string::String>;
|
||||
let mut _6: &str;
|
||||
let mut _7: bool;
|
||||
let _8: std::option::Option<std::string::String>;
|
||||
scope 1 {
|
||||
debug s => _7;
|
||||
debug s => _8;
|
||||
}
|
||||
|
||||
bb0: {
|
||||
|
|
@ -26,11 +27,12 @@ fn foo(_1: Option<String>) -> i32 {
|
|||
}
|
||||
|
||||
bb2: {
|
||||
_6 = <str as PartialEq>::eq(copy _5, const "a") -> [return: bb3, unwind unreachable];
|
||||
_6 = &(*_5);
|
||||
_7 = <str as PartialEq>::eq(copy _6, const "a") -> [return: bb3, unwind unreachable];
|
||||
}
|
||||
|
||||
bb3: {
|
||||
switchInt(move _6) -> [0: bb5, otherwise: bb4];
|
||||
switchInt(move _7) -> [0: bb5, otherwise: bb4];
|
||||
}
|
||||
|
||||
bb4: {
|
||||
|
|
@ -39,15 +41,15 @@ fn foo(_1: Option<String>) -> i32 {
|
|||
}
|
||||
|
||||
bb5: {
|
||||
StorageLive(_7);
|
||||
StorageLive(_8);
|
||||
_2 = const false;
|
||||
_7 = move _1;
|
||||
_8 = move _1;
|
||||
_0 = const 4321_i32;
|
||||
drop(_7) -> [return: bb6, unwind unreachable];
|
||||
drop(_8) -> [return: bb6, unwind unreachable];
|
||||
}
|
||||
|
||||
bb6: {
|
||||
StorageDead(_7);
|
||||
StorageDead(_8);
|
||||
goto -> bb7;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
// skip-filecheck
|
||||
//@ compile-flags: -Z mir-opt-level=0 -C panic=abort
|
||||
|
||||
#![feature(string_deref_patterns)]
|
||||
#![feature(deref_patterns)]
|
||||
#![expect(incomplete_features)]
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// EMIT_MIR string.foo.PreCodegen.after.mir
|
||||
|
|
|
|||
|
|
@ -380,12 +380,6 @@ These tests use the unstable command line option `query-dep-graph` to examine th
|
|||
|
||||
Tests for `#[deprecated]` attribute and `deprecated_in_future` internal lint.
|
||||
|
||||
## `tests/ui/deref-patterns/`: `#![feature(deref_patterns)]` and `#![feature(string_deref_patterns)]`
|
||||
|
||||
Tests for `#![feature(deref_patterns)]` and `#![feature(string_deref_patterns)]`. See [Deref patterns | The Unstable book](https://doc.rust-lang.org/nightly/unstable-book/language-features/deref-patterns.html).
|
||||
|
||||
**FIXME**: May have some overlap with `tests/ui/pattern/deref-patterns`.
|
||||
|
||||
## `tests/ui/derived-errors/`: Derived Error Messages
|
||||
|
||||
Tests for quality of diagnostics involving suppression of cascading errors in some cases to avoid overwhelming the user.
|
||||
|
|
|
|||
|
|
@ -1,7 +0,0 @@
|
|||
// gate-test-string_deref_patterns
|
||||
fn main() {
|
||||
match String::new() {
|
||||
"" | _ => {}
|
||||
//~^ ERROR mismatched types
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
error[E0308]: mismatched types
|
||||
--> $DIR/gate.rs:4:9
|
||||
|
|
||||
LL | match String::new() {
|
||||
| ------------- this expression has type `String`
|
||||
LL | "" | _ => {}
|
||||
| ^^ expected `String`, found `&str`
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
//@ run-pass
|
||||
//@ check-run-results
|
||||
#![feature(string_deref_patterns)]
|
||||
#![feature(deref_patterns)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
test(Some(String::from("42")));
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
//@ check-pass
|
||||
#![feature(string_deref_patterns)]
|
||||
#![feature(deref_patterns)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn main() {
|
||||
match <_ as Default>::default() {
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
//@ check-pass
|
||||
#![feature(string_deref_patterns)]
|
||||
#![feature(deref_patterns)]
|
||||
#![expect(incomplete_features)]
|
||||
|
||||
fn foo(s: &String) -> i32 {
|
||||
match *s {
|
||||
Loading…
Add table
Add a link
Reference in a new issue