@@ -9,10 +9,10 @@ use std::sync::Arc;
99
1010use rustc_data_structures:: fx:: FxIndexMap ;
1111use rustc_hir:: { LangItem , RangeEnd } ;
12+ use rustc_middle:: bug;
1213use rustc_middle:: mir:: * ;
1314use rustc_middle:: ty:: util:: IntTypeExt ;
1415use rustc_middle:: ty:: { self , GenericArg , Ty , TyCtxt } ;
15- use rustc_middle:: { bug, span_bug} ;
1616use rustc_span:: def_id:: DefId ;
1717use rustc_span:: source_map:: Spanned ;
1818use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
@@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
3939 TestKind :: SwitchInt
4040 }
4141 TestableCase :: Constant { value, kind : PatConstKind :: String } => {
42- TestKind :: StringEq { value, pat_ty : match_pair . pattern_ty }
42+ TestKind :: StringEq { value }
4343 }
4444 TestableCase :: Constant { value, kind : PatConstKind :: Float | PatConstKind :: Other } => {
4545 TestKind :: ScalarEq { value, pat_ty : match_pair. pattern_ty }
@@ -141,47 +141,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
141141 self . cfg . terminate ( block, self . source_info ( match_start_span) , terminator) ;
142142 }
143143
144- TestKind :: StringEq { value, pat_ty } => {
144+ TestKind :: StringEq { value } => {
145145 let tcx = self . tcx ;
146146 let success_block = target_block ( TestBranch :: Success ) ;
147147 let fail_block = target_block ( TestBranch :: Failure ) ;
148148
149- let expected_value_ty = value. ty ;
150- let expected_value_operand =
151- self . literal_operand ( test. span , Const :: from_ty_value ( tcx, value) ) ;
152-
153- let mut actual_value_ty = pat_ty;
154- let mut actual_value_place = place;
149+ let ref_str_ty = Ty :: new_imm_ref ( tcx, tcx. lifetimes . re_erased , tcx. types . str_ ) ;
150+ assert ! ( ref_str_ty. is_imm_ref_str( ) , "{ref_str_ty:?}" ) ;
155151
156- match pat_ty. kind ( ) {
157- ty:: Str => {
158- // String literal patterns may have type `str` if `deref_patterns` is
159- // enabled, in order to allow `deref!("..."): String`. In this case, `value`
160- // is of type `&str`, so we compare it to `&place`.
161- if !tcx. features ( ) . deref_patterns ( ) {
162- span_bug ! (
163- test. span,
164- "matching on `str` went through without enabling deref_patterns"
165- ) ;
166- }
167- let re_erased = tcx. lifetimes . re_erased ;
168- let ref_str_ty = Ty :: new_imm_ref ( tcx, re_erased, tcx. types . str_ ) ;
169- let ref_place = self . temp ( ref_str_ty, test. span ) ;
170- // `let ref_place: &str = &place;`
171- self . cfg . push_assign (
172- block,
173- self . source_info ( test. span ) ,
174- ref_place,
175- Rvalue :: Ref ( re_erased, BorrowKind :: Shared , place) ,
176- ) ;
177- actual_value_place = ref_place;
178- actual_value_ty = ref_str_ty;
179- }
180- _ => { }
181- }
152+ // The string constant we're testing against has type `str`, but
153+ // calling `<str as PartialEq>::eq` requires `&str` operands.
154+ //
155+ // Because `str` and `&str` have the same valtree representation,
156+ // we can "cast" to the desired type by just replacing the type.
157+ assert ! ( value. ty. is_str( ) , "unexpected value type for StringEq test: {value:?}" ) ;
158+ let expected_value = ty:: Value { ty : ref_str_ty, valtree : value. valtree } ;
159+ let expected_value_operand =
160+ self . literal_operand ( test. span , Const :: from_ty_value ( tcx, expected_value) ) ;
182161
183- assert_eq ! ( expected_value_ty, actual_value_ty) ;
184- assert ! ( actual_value_ty. is_imm_ref_str( ) ) ;
162+ // Similarly, the scrutinized place has type `str`, but we need `&str`.
163+ // Get a reference by doing `let actual_value_ref_place: &str = &place`.
164+ let actual_value_ref_place = self . temp ( ref_str_ty, test. span ) ;
165+ self . cfg . push_assign (
166+ block,
167+ self . source_info ( test. span ) ,
168+ actual_value_ref_place,
169+ Rvalue :: Ref ( tcx. lifetimes . re_erased , BorrowKind :: Shared , place) ,
170+ ) ;
185171
186172 // Compare two strings using `<str as std::cmp::PartialEq>::eq`.
187173 // (Interestingly this means that exhaustiveness analysis relies, for soundness,
@@ -192,7 +178,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
192178 fail_block,
193179 source_info,
194180 expected_value_operand,
195- Operand :: Copy ( actual_value_place ) ,
181+ Operand :: Copy ( actual_value_ref_place ) ,
196182 ) ;
197183 }
198184
0 commit comments