@@ -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,10 +39,10 @@ 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 } => {
45- TestKind :: ScalarEq { value, pat_ty : match_pair . pattern_ty }
45+ TestKind :: ScalarEq { value }
4646 }
4747
4848 TestableCase :: Range ( ref range) => {
@@ -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) ) ;
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:?}" ) ;
152151
153- let mut actual_value_ty = pat_ty;
154- let mut actual_value_place = place;
155-
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,11 +178,11 @@ 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
199- TestKind :: ScalarEq { value, pat_ty } => {
185+ TestKind :: ScalarEq { value } => {
200186 let tcx = self . tcx ;
201187 let success_block = target_block ( TestBranch :: Success ) ;
202188 let fail_block = target_block ( TestBranch :: Failure ) ;
@@ -205,12 +191,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
205191 let mut expected_value_operand =
206192 self . literal_operand ( test. span , Const :: from_ty_value ( tcx, value) ) ;
207193
208- let mut actual_value_ty = pat_ty;
209194 let mut actual_value_place = place;
210195
211- match pat_ty . kind ( ) {
196+ match value . ty . kind ( ) {
212197 & ty:: Pat ( base, _) => {
213- assert_eq ! ( pat_ty, value. ty) ;
214198 assert ! ( base. is_trivially_pure_clone_copy( ) ) ;
215199
216200 let transmuted_place = self . temp ( base, test. span ) ;
@@ -234,15 +218,13 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
234218 ) ;
235219
236220 actual_value_place = transmuted_place;
237- actual_value_ty = base;
238221 expected_value_operand = Operand :: Copy ( transmuted_expect) ;
239222 expected_value_ty = base;
240223 }
241224 _ => { }
242225 }
243226
244- assert_eq ! ( expected_value_ty, actual_value_ty) ;
245- assert ! ( actual_value_ty. is_scalar( ) ) ;
227+ assert ! ( expected_value_ty. is_scalar( ) ) ;
246228
247229 self . compare (
248230 block,
0 commit comments