@@ -6,7 +6,8 @@ use rustc_ast::{LitKind, StrStyle};
6
6
use rustc_data_structures:: sync:: Lrc ;
7
7
use rustc_errors:: Applicability ;
8
8
use rustc_hir:: { BlockCheckMode , Expr , ExprKind , UnsafeSource } ;
9
- use rustc_lint:: { LateContext , LintContext } ;
9
+ use rustc_lint:: { EarlyContext , LateContext } ;
10
+ use rustc_middle:: ty:: TyCtxt ;
10
11
use rustc_session:: Session ;
11
12
use rustc_span:: source_map:: { original_sp, SourceMap } ;
12
13
use rustc_span:: {
@@ -17,6 +18,30 @@ use std::borrow::Cow;
17
18
use std:: fmt;
18
19
use std:: ops:: Range ;
19
20
21
+ pub trait HasSession {
22
+ fn sess ( & self ) -> & Session ;
23
+ }
24
+ impl HasSession for Session {
25
+ fn sess ( & self ) -> & Session {
26
+ self
27
+ }
28
+ }
29
+ impl HasSession for TyCtxt < ' _ > {
30
+ fn sess ( & self ) -> & Session {
31
+ self . sess
32
+ }
33
+ }
34
+ impl HasSession for EarlyContext < ' _ > {
35
+ fn sess ( & self ) -> & Session {
36
+ :: rustc_lint:: LintContext :: sess ( self )
37
+ }
38
+ }
39
+ impl HasSession for LateContext < ' _ > {
40
+ fn sess ( & self ) -> & Session {
41
+ self . tcx . sess ( )
42
+ }
43
+ }
44
+
20
45
/// Conversion of a value into the range portion of a `Span`.
21
46
pub trait SpanRange : Sized {
22
47
fn into_range ( self ) -> Range < BytePos > ;
@@ -71,27 +96,27 @@ impl IntoSpan for Range<BytePos> {
71
96
pub trait SpanRangeExt : SpanRange {
72
97
/// Gets the source file, and range in the file, of the given span. Returns `None` if the span
73
98
/// extends through multiple files, or is malformed.
74
- fn get_source_text ( self , cx : & impl LintContext ) -> Option < SourceFileRange > {
99
+ fn get_source_text ( self , cx : & impl HasSession ) -> Option < SourceFileRange > {
75
100
get_source_text ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
76
101
}
77
102
78
103
/// Calls the given function with the source text referenced and returns the value. Returns
79
104
/// `None` if the source text cannot be retrieved.
80
- fn with_source_text < T > ( self , cx : & impl LintContext , f : impl for < ' a > FnOnce ( & ' a str ) -> T ) -> Option < T > {
105
+ fn with_source_text < T > ( self , cx : & impl HasSession , f : impl for < ' a > FnOnce ( & ' a str ) -> T ) -> Option < T > {
81
106
with_source_text ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , f)
82
107
}
83
108
84
109
/// Checks if the referenced source text satisfies the given predicate. Returns `false` if the
85
110
/// source text cannot be retrieved.
86
- fn check_source_text ( self , cx : & impl LintContext , pred : impl for < ' a > FnOnce ( & ' a str ) -> bool ) -> bool {
111
+ fn check_source_text ( self , cx : & impl HasSession , pred : impl for < ' a > FnOnce ( & ' a str ) -> bool ) -> bool {
87
112
self . with_source_text ( cx, pred) . unwrap_or ( false )
88
113
}
89
114
90
115
/// Calls the given function with the both the text of the source file and the referenced range,
91
116
/// and returns the value. Returns `None` if the source text cannot be retrieved.
92
117
fn with_source_text_and_range < T > (
93
118
self ,
94
- cx : & impl LintContext ,
119
+ cx : & impl HasSession ,
95
120
f : impl for < ' a > FnOnce ( & ' a str , Range < usize > ) -> T ,
96
121
) -> Option < T > {
97
122
with_source_text_and_range ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , f)
@@ -104,30 +129,30 @@ pub trait SpanRangeExt: SpanRange {
104
129
/// The new range must reside within the same source file.
105
130
fn map_range (
106
131
self ,
107
- cx : & impl LintContext ,
132
+ cx : & impl HasSession ,
108
133
f : impl for < ' a > FnOnce ( & ' a str , Range < usize > ) -> Option < Range < usize > > ,
109
134
) -> Option < Range < BytePos > > {
110
135
map_range ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , f)
111
136
}
112
137
113
138
/// Extends the range to include all preceding whitespace characters.
114
- fn with_leading_whitespace ( self , cx : & impl LintContext ) -> Range < BytePos > {
139
+ fn with_leading_whitespace ( self , cx : & impl HasSession ) -> Range < BytePos > {
115
140
with_leading_whitespace ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
116
141
}
117
142
118
143
/// Trims the leading whitespace from the range.
119
- fn trim_start ( self , cx : & impl LintContext ) -> Range < BytePos > {
144
+ fn trim_start ( self , cx : & impl HasSession ) -> Range < BytePos > {
120
145
trim_start ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
121
146
}
122
147
123
148
/// Writes the referenced source text to the given writer. Will return `Err` if the source text
124
149
/// could not be retrieved.
125
- fn write_source_text_to ( self , cx : & impl LintContext , dst : & mut impl fmt:: Write ) -> fmt:: Result {
150
+ fn write_source_text_to ( self , cx : & impl HasSession , dst : & mut impl fmt:: Write ) -> fmt:: Result {
126
151
write_source_text_to ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , dst)
127
152
}
128
153
129
154
/// Extracts the referenced source text as an owned string.
130
- fn source_text_to_string ( self , cx : & impl LintContext ) -> Option < String > {
155
+ fn source_text_to_string ( self , cx : & impl HasSession ) -> Option < String > {
131
156
self . with_source_text ( cx, ToOwned :: to_owned)
132
157
}
133
158
}
@@ -227,15 +252,15 @@ impl SourceFileRange {
227
252
}
228
253
229
254
/// Like `snippet_block`, but add braces if the expr is not an `ExprKind::Block`.
230
- pub fn expr_block < T : LintContext > (
231
- cx : & T ,
255
+ pub fn expr_block (
256
+ sess : & impl HasSession ,
232
257
expr : & Expr < ' _ > ,
233
258
outer : SyntaxContext ,
234
259
default : & str ,
235
260
indent_relative_to : Option < Span > ,
236
261
app : & mut Applicability ,
237
262
) -> String {
238
- let ( code, from_macro) = snippet_block_with_context ( cx , expr. span , outer, default, indent_relative_to, app) ;
263
+ let ( code, from_macro) = snippet_block_with_context ( sess , expr. span , outer, default, indent_relative_to, app) ;
239
264
if !from_macro
240
265
&& let ExprKind :: Block ( block, _) = expr. kind
241
266
&& block. rules != BlockCheckMode :: UnsafeBlock ( UnsafeSource :: UserProvided )
@@ -260,13 +285,13 @@ pub fn expr_block<T: LintContext>(
260
285
/// let x = ();
261
286
/// // ^^^^^^^^^^
262
287
/// ```
263
- pub fn first_line_of_span < T : LintContext > ( cx : & T , span : Span ) -> Span {
264
- first_char_in_first_line ( cx , span) . map_or ( span, |first_char_pos| span. with_lo ( first_char_pos) )
288
+ pub fn first_line_of_span ( sess : & impl HasSession , span : Span ) -> Span {
289
+ first_char_in_first_line ( sess , span) . map_or ( span, |first_char_pos| span. with_lo ( first_char_pos) )
265
290
}
266
291
267
- fn first_char_in_first_line < T : LintContext > ( cx : & T , span : Span ) -> Option < BytePos > {
268
- let line_span = line_span ( cx , span) ;
269
- snippet_opt ( cx , line_span) . and_then ( |snip| {
292
+ fn first_char_in_first_line ( sess : & impl HasSession , span : Span ) -> Option < BytePos > {
293
+ let line_span = line_span ( sess , span) ;
294
+ snippet_opt ( sess , line_span) . and_then ( |snip| {
270
295
snip. find ( |c : char | !c. is_whitespace ( ) )
271
296
. map ( |pos| line_span. lo ( ) + BytePos :: from_usize ( pos) )
272
297
} )
@@ -281,9 +306,9 @@ fn first_char_in_first_line<T: LintContext>(cx: &T, span: Span) -> Option<BytePo
281
306
/// let x = ();
282
307
/// // ^^^^^^^^^^^^^^
283
308
/// ```
284
- fn line_span < T : LintContext > ( cx : & T , span : Span ) -> Span {
309
+ fn line_span ( sess : & impl HasSession , span : Span ) -> Span {
285
310
let span = original_sp ( span, DUMMY_SP ) ;
286
- let SourceFileAndLine { sf, line } = cx . sess ( ) . source_map ( ) . lookup_line ( span. lo ( ) ) . unwrap ( ) ;
311
+ let SourceFileAndLine { sf, line } = sess . sess ( ) . source_map ( ) . lookup_line ( span. lo ( ) ) . unwrap ( ) ;
287
312
let line_start = sf. lines ( ) [ line] ;
288
313
let line_start = sf. absolute_position ( line_start) ;
289
314
span. with_lo ( line_start)
@@ -297,13 +322,13 @@ fn line_span<T: LintContext>(cx: &T, span: Span) -> Span {
297
322
/// let x = ();
298
323
/// // ^^ -- will return 4
299
324
/// ```
300
- pub fn indent_of < T : LintContext > ( cx : & T , span : Span ) -> Option < usize > {
301
- snippet_opt ( cx , line_span ( cx , span) ) . and_then ( |snip| snip. find ( |c : char | !c. is_whitespace ( ) ) )
325
+ pub fn indent_of ( sess : & impl HasSession , span : Span ) -> Option < usize > {
326
+ snippet_opt ( sess , line_span ( sess , span) ) . and_then ( |snip| snip. find ( |c : char | !c. is_whitespace ( ) ) )
302
327
}
303
328
304
329
/// Gets a snippet of the indentation of the line of a span
305
- pub fn snippet_indent < T : LintContext > ( cx : & T , span : Span ) -> Option < String > {
306
- snippet_opt ( cx , line_span ( cx , span) ) . map ( |mut s| {
330
+ pub fn snippet_indent ( sess : & impl HasSession , span : Span ) -> Option < String > {
331
+ snippet_opt ( sess , line_span ( sess , span) ) . map ( |mut s| {
307
332
let len = s. len ( ) - s. trim_start ( ) . len ( ) ;
308
333
s. truncate ( len) ;
309
334
s
@@ -315,8 +340,8 @@ pub fn snippet_indent<T: LintContext>(cx: &T, span: Span) -> Option<String> {
315
340
// sources that the user has no control over.
316
341
// For some reason these attributes don't have any expansion info on them, so
317
342
// we have to check it this way until there is a better way.
318
- pub fn is_present_in_source < T : LintContext > ( cx : & T , span : Span ) -> bool {
319
- if let Some ( snippet) = snippet_opt ( cx , span) {
343
+ pub fn is_present_in_source ( sess : & impl HasSession , span : Span ) -> bool {
344
+ if let Some ( snippet) = snippet_opt ( sess , span) {
320
345
if snippet. is_empty ( ) {
321
346
return false ;
322
347
}
@@ -407,8 +432,8 @@ fn reindent_multiline_inner(s: &str, ignore_first: bool, indent: Option<usize>,
407
432
/// snippet(cx, span1, "..") // -> "value"
408
433
/// snippet(cx, span2, "..") // -> "Vec::new()"
409
434
/// ```
410
- pub fn snippet < ' a , T : LintContext > ( cx : & T , span : Span , default : & ' a str ) -> Cow < ' a , str > {
411
- snippet_opt ( cx , span) . map_or_else ( || Cow :: Borrowed ( default) , From :: from)
435
+ pub fn snippet < ' a > ( sess : & impl HasSession , span : Span , default : & ' a str ) -> Cow < ' a , str > {
436
+ snippet_opt ( sess , span) . map_or_else ( || Cow :: Borrowed ( default) , From :: from)
412
437
}
413
438
414
439
/// Same as [`snippet`], but it adapts the applicability level by following rules:
@@ -417,13 +442,13 @@ pub fn snippet<'a, T: LintContext>(cx: &T, span: Span, default: &'a str) -> Cow<
417
442
/// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`.
418
443
/// - If the default value is used and the applicability level is `MachineApplicable`, change it to
419
444
/// `HasPlaceholders`
420
- pub fn snippet_with_applicability < ' a , T : LintContext > (
421
- cx : & T ,
445
+ pub fn snippet_with_applicability < ' a > (
446
+ sess : & impl HasSession ,
422
447
span : Span ,
423
448
default : & ' a str ,
424
449
applicability : & mut Applicability ,
425
450
) -> Cow < ' a , str > {
426
- snippet_with_applicability_sess ( cx . sess ( ) , span, default, applicability)
451
+ snippet_with_applicability_sess ( sess . sess ( ) , span, default, applicability)
427
452
}
428
453
429
454
fn snippet_with_applicability_sess < ' a > (
@@ -435,7 +460,7 @@ fn snippet_with_applicability_sess<'a>(
435
460
if * applicability != Applicability :: Unspecified && span. from_expansion ( ) {
436
461
* applicability = Applicability :: MaybeIncorrect ;
437
462
}
438
- snippet_opt_sess ( sess, span) . map_or_else (
463
+ snippet_opt ( sess, span) . map_or_else (
439
464
|| {
440
465
if * applicability == Applicability :: MachineApplicable {
441
466
* applicability = Applicability :: HasPlaceholders ;
@@ -447,12 +472,8 @@ fn snippet_with_applicability_sess<'a>(
447
472
}
448
473
449
474
/// Converts a span to a code snippet. Returns `None` if not available.
450
- pub fn snippet_opt ( cx : & impl LintContext , span : Span ) -> Option < String > {
451
- snippet_opt_sess ( cx. sess ( ) , span)
452
- }
453
-
454
- fn snippet_opt_sess ( sess : & Session , span : Span ) -> Option < String > {
455
- sess. source_map ( ) . span_to_snippet ( span) . ok ( )
475
+ pub fn snippet_opt ( sess : & impl HasSession , span : Span ) -> Option < String > {
476
+ sess. sess ( ) . source_map ( ) . span_to_snippet ( span) . ok ( )
456
477
}
457
478
458
479
/// Converts a span (from a block) to a code snippet if available, otherwise use default.
@@ -489,41 +510,41 @@ fn snippet_opt_sess(sess: &Session, span: Span) -> Option<String> {
489
510
/// } // aligned with `if`
490
511
/// ```
491
512
/// Note that the first line of the snippet always has 0 indentation.
492
- pub fn snippet_block < ' a , T : LintContext > (
493
- cx : & T ,
513
+ pub fn snippet_block < ' a > (
514
+ sess : & impl HasSession ,
494
515
span : Span ,
495
516
default : & ' a str ,
496
517
indent_relative_to : Option < Span > ,
497
518
) -> Cow < ' a , str > {
498
- let snip = snippet ( cx , span, default) ;
499
- let indent = indent_relative_to. and_then ( |s| indent_of ( cx , s) ) ;
519
+ let snip = snippet ( sess , span, default) ;
520
+ let indent = indent_relative_to. and_then ( |s| indent_of ( sess , s) ) ;
500
521
reindent_multiline ( snip, true , indent)
501
522
}
502
523
503
524
/// Same as `snippet_block`, but adapts the applicability level by the rules of
504
525
/// `snippet_with_applicability`.
505
526
pub fn snippet_block_with_applicability < ' a > (
506
- cx : & impl LintContext ,
527
+ sess : & impl HasSession ,
507
528
span : Span ,
508
529
default : & ' a str ,
509
530
indent_relative_to : Option < Span > ,
510
531
applicability : & mut Applicability ,
511
532
) -> Cow < ' a , str > {
512
- let snip = snippet_with_applicability ( cx , span, default, applicability) ;
513
- let indent = indent_relative_to. and_then ( |s| indent_of ( cx , s) ) ;
533
+ let snip = snippet_with_applicability ( sess , span, default, applicability) ;
534
+ let indent = indent_relative_to. and_then ( |s| indent_of ( sess , s) ) ;
514
535
reindent_multiline ( snip, true , indent)
515
536
}
516
537
517
538
pub fn snippet_block_with_context < ' a > (
518
- cx : & impl LintContext ,
539
+ sess : & impl HasSession ,
519
540
span : Span ,
520
541
outer : SyntaxContext ,
521
542
default : & ' a str ,
522
543
indent_relative_to : Option < Span > ,
523
544
app : & mut Applicability ,
524
545
) -> ( Cow < ' a , str > , bool ) {
525
- let ( snip, from_macro) = snippet_with_context ( cx , span, outer, default, app) ;
526
- let indent = indent_relative_to. and_then ( |s| indent_of ( cx , s) ) ;
546
+ let ( snip, from_macro) = snippet_with_context ( sess , span, outer, default, app) ;
547
+ let indent = indent_relative_to. and_then ( |s| indent_of ( sess , s) ) ;
527
548
( reindent_multiline ( snip, true , indent) , from_macro)
528
549
}
529
550
@@ -537,13 +558,13 @@ pub fn snippet_block_with_context<'a>(
537
558
///
538
559
/// This will also return whether or not the snippet is a macro call.
539
560
pub fn snippet_with_context < ' a > (
540
- cx : & impl LintContext ,
561
+ sess : & impl HasSession ,
541
562
span : Span ,
542
563
outer : SyntaxContext ,
543
564
default : & ' a str ,
544
565
applicability : & mut Applicability ,
545
566
) -> ( Cow < ' a , str > , bool ) {
546
- snippet_with_context_sess ( cx . sess ( ) , span, outer, default, applicability)
567
+ snippet_with_context_sess ( sess . sess ( ) , span, outer, default, applicability)
547
568
}
548
569
549
570
fn snippet_with_context_sess < ' a > (
@@ -661,15 +682,15 @@ pub fn trim_span(sm: &SourceMap, span: Span) -> Span {
661
682
/// writeln!(o, "") -> writeln!(o, "")
662
683
/// ^^ ^^^^
663
684
/// ```
664
- pub fn expand_past_previous_comma ( cx : & LateContext < ' _ > , span : Span ) -> Span {
665
- let extended = cx . sess ( ) . source_map ( ) . span_extend_to_prev_char ( span, ',' , true ) ;
685
+ pub fn expand_past_previous_comma ( sess : & impl HasSession , span : Span ) -> Span {
686
+ let extended = sess . sess ( ) . source_map ( ) . span_extend_to_prev_char ( span, ',' , true ) ;
666
687
extended. with_lo ( extended. lo ( ) - BytePos ( 1 ) )
667
688
}
668
689
669
690
/// Converts `expr` to a `char` literal if it's a `str` literal containing a single
670
691
/// character (or a single byte with `ascii_only`)
671
692
pub fn str_literal_to_char_literal (
672
- cx : & LateContext < ' _ > ,
693
+ sess : & impl HasSession ,
673
694
expr : & Expr < ' _ > ,
674
695
applicability : & mut Applicability ,
675
696
ascii_only : bool ,
@@ -684,7 +705,7 @@ pub fn str_literal_to_char_literal(
684
705
}
685
706
&& len == 1
686
707
{
687
- let snip = snippet_with_applicability ( cx , expr. span , string, applicability) ;
708
+ let snip = snippet_with_applicability ( sess , expr. span , string, applicability) ;
688
709
let ch = if let StrStyle :: Raw ( nhash) = style {
689
710
let nhash = nhash as usize ;
690
711
// for raw string: r##"a"##
0 commit comments