2
2
3
3
mod check_match;
4
4
mod const_to_pat;
5
+ mod migration;
5
6
6
7
use std:: cmp:: Ordering ;
7
8
8
9
use rustc_abi:: { FieldIdx , Integer } ;
9
- use rustc_errors:: MultiSpan ;
10
10
use rustc_errors:: codes:: * ;
11
11
use rustc_hir:: def:: { CtorOf , DefKind , Res } ;
12
12
use rustc_hir:: pat_util:: EnumerateAndAdjustIterator ;
13
- use rustc_hir:: { self as hir, ByRef , Mutability , RangeEnd } ;
13
+ use rustc_hir:: { self as hir, RangeEnd } ;
14
14
use rustc_index:: Idx ;
15
- use rustc_lint as lint;
16
15
use rustc_middle:: mir:: interpret:: LitToConstInput ;
17
16
use rustc_middle:: thir:: {
18
17
Ascription , FieldPat , LocalVarId , Pat , PatKind , PatRange , PatRangeBoundary ,
@@ -25,8 +24,8 @@ use rustc_span::{ErrorGuaranteed, Span};
25
24
use tracing:: { debug, instrument} ;
26
25
27
26
pub ( crate ) use self :: check_match:: check_match;
27
+ use self :: migration:: PatMigration ;
28
28
use crate :: errors:: * ;
29
- use crate :: fluent_generated as fluent;
30
29
use crate :: thir:: util:: UserAnnotatedTyHelpers ;
31
30
32
31
struct PatCtxt < ' a , ' tcx > {
@@ -35,7 +34,7 @@ struct PatCtxt<'a, 'tcx> {
35
34
typeck_results : & ' a ty:: TypeckResults < ' tcx > ,
36
35
37
36
/// Used by the Rust 2024 migration lint.
38
- rust_2024_migration_suggestion : Option < Rust2024IncompatiblePatSugg < ' a > > ,
37
+ rust_2024_migration : Option < PatMigration < ' a > > ,
39
38
}
40
39
41
40
pub ( super ) fn pat_from_hir < ' a , ' tcx > (
@@ -48,42 +47,15 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
48
47
tcx,
49
48
typing_env,
50
49
typeck_results,
51
- rust_2024_migration_suggestion : typeck_results
50
+ rust_2024_migration : typeck_results
52
51
. rust_2024_migration_desugared_pats ( )
53
52
. get ( pat. hir_id )
54
- . map ( |labels| Rust2024IncompatiblePatSugg {
55
- suggestion : Vec :: new ( ) ,
56
- ref_pattern_count : 0 ,
57
- binding_mode_count : 0 ,
58
- labels : labels. as_slice ( ) ,
59
- } ) ,
53
+ . map ( PatMigration :: new) ,
60
54
} ;
61
55
let result = pcx. lower_pattern ( pat) ;
62
56
debug ! ( "pat_from_hir({:?}) = {:?}" , pat, result) ;
63
- if let Some ( sugg) = pcx. rust_2024_migration_suggestion {
64
- let mut spans = MultiSpan :: from_spans ( sugg. labels . iter ( ) . map ( |( span, _) | * span) . collect ( ) ) ;
65
- for ( span, label) in sugg. labels {
66
- spans. push_span_label ( * span, label. clone ( ) ) ;
67
- }
68
- // If a relevant span is from at least edition 2024, this is a hard error.
69
- let is_hard_error = spans. primary_spans ( ) . iter ( ) . any ( |span| span. at_least_rust_2024 ( ) ) ;
70
- if is_hard_error {
71
- let mut err =
72
- tcx. dcx ( ) . struct_span_err ( spans, fluent:: mir_build_rust_2024_incompatible_pat) ;
73
- if let Some ( info) = lint:: builtin:: RUST_2024_INCOMPATIBLE_PAT . future_incompatible {
74
- // provide the same reference link as the lint
75
- err. note ( format ! ( "for more information, see {}" , info. reference) ) ;
76
- }
77
- err. subdiagnostic ( sugg) ;
78
- err. emit ( ) ;
79
- } else {
80
- tcx. emit_node_span_lint (
81
- lint:: builtin:: RUST_2024_INCOMPATIBLE_PAT ,
82
- pat. hir_id ,
83
- spans,
84
- Rust2024IncompatiblePat { sugg } ,
85
- ) ;
86
- }
57
+ if let Some ( m) = pcx. rust_2024_migration {
58
+ m. emit ( tcx, pat. hir_id ) ;
87
59
}
88
60
result
89
61
}
@@ -129,25 +101,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
129
101
} )
130
102
} ) ;
131
103
132
- if let Some ( s ) = & mut self . rust_2024_migration_suggestion
104
+ if let Some ( m ) = & mut self . rust_2024_migration
133
105
&& !adjustments. is_empty ( )
134
106
{
135
- let suggestion_str: String = adjustments
136
- . iter ( )
137
- . map ( |ref_ty| {
138
- let & ty:: Ref ( _, _, mutbl) = ref_ty. kind ( ) else {
139
- span_bug ! ( pat. span, "pattern implicitly dereferences a non-ref type" ) ;
140
- } ;
141
-
142
- match mutbl {
143
- ty:: Mutability :: Not => "&" ,
144
- ty:: Mutability :: Mut => "&mut " ,
145
- }
146
- } )
147
- . collect ( ) ;
148
- s. suggestion . push ( ( pat. span . shrink_to_lo ( ) , suggestion_str) ) ;
149
- s. ref_pattern_count += adjustments. len ( ) ;
150
- } ;
107
+ m. visit_implicit_derefs ( pat. span , adjustments) ;
108
+ }
151
109
152
110
adjusted_pat
153
111
}
@@ -364,19 +322,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
364
322
. get ( pat. hir_id )
365
323
. expect ( "missing binding mode" ) ;
366
324
367
- if let Some ( s) = & mut self . rust_2024_migration_suggestion
368
- && explicit_ba. 0 == ByRef :: No
369
- && let ByRef :: Yes ( mutbl) = mode. 0
370
- {
371
- let sugg_str = match mutbl {
372
- Mutability :: Not => "ref " ,
373
- Mutability :: Mut => "ref mut " ,
374
- } ;
375
- s. suggestion . push ( (
376
- pat. span . with_lo ( ident. span . lo ( ) ) . shrink_to_lo ( ) ,
377
- sugg_str. to_owned ( ) ,
378
- ) ) ;
379
- s. binding_mode_count += 1 ;
325
+ if let Some ( m) = & mut self . rust_2024_migration {
326
+ m. visit_binding ( pat. span , mode, explicit_ba, ident) ;
380
327
}
381
328
382
329
// A ref x pattern is the same node used for x, and as such it has
0 commit comments