@@ -6,7 +6,6 @@ use rustc_infer::traits::Obligation;
6
6
use rustc_middle:: mir;
7
7
use rustc_middle:: thir:: { FieldPat , Pat , PatKind } ;
8
8
use rustc_middle:: ty:: { self , Ty , TyCtxt , ValTree } ;
9
- use rustc_session:: lint;
10
9
use rustc_span:: { ErrorGuaranteed , Span } ;
11
10
use rustc_target:: abi:: { FieldIdx , VariantIdx } ;
12
11
use rustc_trait_selection:: traits:: query:: evaluate_obligation:: InferCtxtExt ;
@@ -16,8 +15,8 @@ use std::cell::Cell;
16
15
17
16
use super :: PatCtxt ;
18
17
use crate :: errors:: {
19
- IndirectStructuralMatch , InvalidPattern , NaNPattern , PointerPattern , TypeNotPartialEq ,
20
- TypeNotStructural , UnionPattern , UnsizedPattern ,
18
+ InvalidPattern , NaNPattern , PointerPattern , TypeNotPartialEq , TypeNotStructural , UnionPattern ,
19
+ UnsizedPattern ,
21
20
} ;
22
21
23
22
impl < ' a , ' tcx > PatCtxt < ' a , ' tcx > {
@@ -49,15 +48,6 @@ struct ConstToPat<'tcx> {
49
48
// value.
50
49
saw_const_match_error : Cell < Option < ErrorGuaranteed > > ,
51
50
52
- // This tracks if we emitted some diagnostic for a given const value, so that
53
- // we will not subsequently issue an irrelevant lint for the same const
54
- // value.
55
- saw_const_match_lint : Cell < bool > ,
56
-
57
- // For backcompat we need to keep allowing non-structurally-eq types behind references.
58
- // See also all the `cant-hide-behind` tests.
59
- behind_reference : Cell < bool > ,
60
-
61
51
// inference context used for checking `T: Structural` bounds.
62
52
infcx : InferCtxt < ' tcx > ,
63
53
@@ -84,8 +74,6 @@ impl<'tcx> ConstToPat<'tcx> {
84
74
infcx,
85
75
param_env : pat_ctxt. param_env ,
86
76
saw_const_match_error : Cell :: new ( None ) ,
87
- saw_const_match_lint : Cell :: new ( false ) ,
88
- behind_reference : Cell :: new ( false ) ,
89
77
treat_byte_string_as_slice : pat_ctxt
90
78
. typeck_results
91
79
. treat_byte_string_as_slice
@@ -197,15 +185,12 @@ impl<'tcx> ConstToPat<'tcx> {
197
185
// complained about structural match violations there, so we don't
198
186
// have to check anything any more.
199
187
}
200
- } else if !have_valtree && ! self . saw_const_match_lint . get ( ) {
188
+ } else if !have_valtree {
201
189
// The only way valtree construction can fail without the structural match
202
190
// checker finding a violation is if there is a pointer somewhere.
203
- self . tcx ( ) . emit_node_span_lint (
204
- lint:: builtin:: POINTER_STRUCTURAL_MATCH ,
205
- self . id ,
206
- self . span ,
207
- PointerPattern ,
208
- ) ;
191
+ let e = self . tcx ( ) . dcx ( ) . emit_err ( PointerPattern { span : self . span } ) ;
192
+ let kind = PatKind :: Error ( e) ;
193
+ return Box :: new ( Pat { span : self . span , ty : cv. ty ( ) , kind } ) ;
209
194
}
210
195
211
196
// Always check for `PartialEq` if we had no other errors yet.
@@ -274,36 +259,11 @@ impl<'tcx> ConstToPat<'tcx> {
274
259
cv : ValTree < ' tcx > ,
275
260
ty : Ty < ' tcx > ,
276
261
) -> Result < Box < Pat < ' tcx > > , FallbackToOpaqueConst > {
277
- let id = self . id ;
278
262
let span = self . span ;
279
263
let tcx = self . tcx ( ) ;
280
264
let param_env = self . param_env ;
281
265
282
266
let kind = match ty. kind ( ) {
283
- // If the type is not structurally comparable, just emit the constant directly,
284
- // causing the pattern match code to treat it opaquely.
285
- // FIXME: This code doesn't emit errors itself, the caller emits the errors.
286
- // So instead of specific errors, you just get blanket errors about the whole
287
- // const type. See
288
- // https://github.com/rust-lang/rust/pull/70743#discussion_r404701963 for
289
- // details.
290
- // Backwards compatibility hack because we can't cause hard errors on these
291
- // types, so we compare them via `PartialEq::eq` at runtime.
292
- ty:: Adt ( ..) if !self . type_marked_structural ( ty) && self . behind_reference . get ( ) => {
293
- if self . saw_const_match_error . get ( ) . is_none ( ) && !self . saw_const_match_lint . get ( ) {
294
- self . saw_const_match_lint . set ( true ) ;
295
- tcx. emit_node_span_lint (
296
- lint:: builtin:: INDIRECT_STRUCTURAL_MATCH ,
297
- id,
298
- span,
299
- IndirectStructuralMatch { non_sm_ty : ty } ,
300
- ) ;
301
- }
302
- // Since we are behind a reference, we can just bubble the error up so we get a
303
- // constant at reference type, making it easy to let the fallback call
304
- // `PartialEq::eq` on it.
305
- return Err ( FallbackToOpaqueConst ) ;
306
- }
307
267
ty:: FnDef ( ..) => {
308
268
let e = tcx. dcx ( ) . emit_err ( InvalidPattern { span, non_sm_ty : ty } ) ;
309
269
self . saw_const_match_error . set ( Some ( e) ) ;
@@ -377,38 +337,6 @@ impl<'tcx> ConstToPat<'tcx> {
377
337
ty:: Str => {
378
338
PatKind :: Constant { value : mir:: Const :: Ty ( ty:: Const :: new_value ( tcx, cv, ty) ) }
379
339
}
380
- // Backwards compatibility hack: support references to non-structural types,
381
- // but hard error if we aren't behind a double reference. We could just use
382
- // the fallback code path below, but that would allow *more* of this fishy
383
- // code to compile, as then it only goes through the future incompat lint
384
- // instead of a hard error.
385
- ty:: Adt ( _, _) if !self . type_marked_structural ( * pointee_ty) => {
386
- if self . behind_reference . get ( ) {
387
- if self . saw_const_match_error . get ( ) . is_none ( )
388
- && !self . saw_const_match_lint . get ( )
389
- {
390
- self . saw_const_match_lint . set ( true ) ;
391
- tcx. emit_node_span_lint (
392
- lint:: builtin:: INDIRECT_STRUCTURAL_MATCH ,
393
- self . id ,
394
- span,
395
- IndirectStructuralMatch { non_sm_ty : * pointee_ty } ,
396
- ) ;
397
- }
398
- return Err ( FallbackToOpaqueConst ) ;
399
- } else {
400
- if let Some ( e) = self . saw_const_match_error . get ( ) {
401
- // We already errored. Signal that in the pattern, so that follow up errors can be silenced.
402
- PatKind :: Error ( e)
403
- } else {
404
- let err = TypeNotStructural { span, non_sm_ty : * pointee_ty } ;
405
- let e = tcx. dcx ( ) . emit_err ( err) ;
406
- self . saw_const_match_error . set ( Some ( e) ) ;
407
- // We errored. Signal that in the pattern, so that follow up errors can be silenced.
408
- PatKind :: Error ( e)
409
- }
410
- }
411
- }
412
340
// All other references are converted into deref patterns and then recursively
413
341
// convert the dereferenced constant to a pattern that is the sub-pattern of the
414
342
// deref pattern.
@@ -419,7 +347,6 @@ impl<'tcx> ConstToPat<'tcx> {
419
347
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
420
348
PatKind :: Error ( e)
421
349
} else {
422
- let old = self . behind_reference . replace ( true ) ;
423
350
// `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when
424
351
// matching against references, you can only use byte string literals.
425
352
// The typechecker has a special case for byte string literals, by treating them
@@ -434,7 +361,6 @@ impl<'tcx> ConstToPat<'tcx> {
434
361
} ;
435
362
// References have the same valtree representation as their pointee.
436
363
let subpattern = self . recur ( cv, pointee_ty) ?;
437
- self . behind_reference . set ( old) ;
438
364
PatKind :: Deref { subpattern }
439
365
}
440
366
}
0 commit comments