@@ -6,7 +6,8 @@ use rustc_ast::{LitKind, StrStyle};
66use rustc_data_structures:: sync:: Lrc ;
77use rustc_errors:: Applicability ;
88use rustc_hir:: { BlockCheckMode , Expr , ExprKind , UnsafeSource } ;
9- use rustc_lint:: { LateContext , LintContext } ;
9+ use rustc_lint:: { EarlyContext , LateContext } ;
10+ use rustc_middle:: ty:: TyCtxt ;
1011use rustc_session:: Session ;
1112use rustc_span:: source_map:: { original_sp, SourceMap } ;
1213use rustc_span:: {
@@ -17,6 +18,30 @@ use std::borrow::Cow;
1718use std:: fmt;
1819use std:: ops:: Range ;
1920
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+
2045/// Conversion of a value into the range portion of a `Span`.
2146pub trait SpanRange : Sized {
2247 fn into_range ( self ) -> Range < BytePos > ;
@@ -71,27 +96,27 @@ impl IntoSpan for Range<BytePos> {
7196pub trait SpanRangeExt : SpanRange {
7297 /// Gets the source file, and range in the file, of the given span. Returns `None` if the span
7398 /// 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 > {
75100 get_source_text ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
76101 }
77102
78103 /// Calls the given function with the source text referenced and returns the value. Returns
79104 /// `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 > {
81106 with_source_text ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , f)
82107 }
83108
84109 /// Checks if the referenced source text satisfies the given predicate. Returns `false` if the
85110 /// 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 {
87112 self . with_source_text ( cx, pred) . unwrap_or ( false )
88113 }
89114
90115 /// Calls the given function with the both the text of the source file and the referenced range,
91116 /// and returns the value. Returns `None` if the source text cannot be retrieved.
92117 fn with_source_text_and_range < T > (
93118 self ,
94- cx : & impl LintContext ,
119+ cx : & impl HasSession ,
95120 f : impl for < ' a > FnOnce ( & ' a str , Range < usize > ) -> T ,
96121 ) -> Option < T > {
97122 with_source_text_and_range ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , f)
@@ -104,30 +129,30 @@ pub trait SpanRangeExt: SpanRange {
104129 /// The new range must reside within the same source file.
105130 fn map_range (
106131 self ,
107- cx : & impl LintContext ,
132+ cx : & impl HasSession ,
108133 f : impl for < ' a > FnOnce ( & ' a str , Range < usize > ) -> Option < Range < usize > > ,
109134 ) -> Option < Range < BytePos > > {
110135 map_range ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , f)
111136 }
112137
113138 /// 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 > {
115140 with_leading_whitespace ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
116141 }
117142
118143 /// 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 > {
120145 trim_start ( cx. sess ( ) . source_map ( ) , self . into_range ( ) )
121146 }
122147
123148 /// Writes the referenced source text to the given writer. Will return `Err` if the source text
124149 /// 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 {
126151 write_source_text_to ( cx. sess ( ) . source_map ( ) , self . into_range ( ) , dst)
127152 }
128153
129154 /// 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 > {
131156 self . with_source_text ( cx, ToOwned :: to_owned)
132157 }
133158}
@@ -227,15 +252,15 @@ impl SourceFileRange {
227252}
228253
229254/// 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 ,
232257 expr : & Expr < ' _ > ,
233258 outer : SyntaxContext ,
234259 default : & str ,
235260 indent_relative_to : Option < Span > ,
236261 app : & mut Applicability ,
237262) -> 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) ;
239264 if !from_macro
240265 && let ExprKind :: Block ( block, _) = expr. kind
241266 && block. rules != BlockCheckMode :: UnsafeBlock ( UnsafeSource :: UserProvided )
@@ -260,13 +285,13 @@ pub fn expr_block<T: LintContext>(
260285/// let x = ();
261286/// // ^^^^^^^^^^
262287/// ```
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) )
265290}
266291
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| {
270295 snip. find ( |c : char | !c. is_whitespace ( ) )
271296 . map ( |pos| line_span. lo ( ) + BytePos :: from_usize ( pos) )
272297 } )
@@ -281,9 +306,9 @@ fn first_char_in_first_line<T: LintContext>(cx: &T, span: Span) -> Option<BytePo
281306/// let x = ();
282307/// // ^^^^^^^^^^^^^^
283308/// ```
284- fn line_span < T : LintContext > ( cx : & T , span : Span ) -> Span {
309+ fn line_span ( sess : & impl HasSession , span : Span ) -> Span {
285310 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 ( ) ;
287312 let line_start = sf. lines ( ) [ line] ;
288313 let line_start = sf. absolute_position ( line_start) ;
289314 span. with_lo ( line_start)
@@ -297,13 +322,13 @@ fn line_span<T: LintContext>(cx: &T, span: Span) -> Span {
297322/// let x = ();
298323/// // ^^ -- will return 4
299324/// ```
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 ( ) ) )
302327}
303328
304329/// 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| {
307332 let len = s. len ( ) - s. trim_start ( ) . len ( ) ;
308333 s. truncate ( len) ;
309334 s
@@ -315,8 +340,8 @@ pub fn snippet_indent<T: LintContext>(cx: &T, span: Span) -> Option<String> {
315340// sources that the user has no control over.
316341// For some reason these attributes don't have any expansion info on them, so
317342// 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) {
320345 if snippet. is_empty ( ) {
321346 return false ;
322347 }
@@ -407,8 +432,8 @@ fn reindent_multiline_inner(s: &str, ignore_first: bool, indent: Option<usize>,
407432/// snippet(cx, span1, "..") // -> "value"
408433/// snippet(cx, span2, "..") // -> "Vec::new()"
409434/// ```
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)
412437}
413438
414439/// 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<
417442/// - If the span is inside a macro, change the applicability level to `MaybeIncorrect`.
418443/// - If the default value is used and the applicability level is `MachineApplicable`, change it to
419444/// `HasPlaceholders`
420- pub fn snippet_with_applicability < ' a , T : LintContext > (
421- cx : & T ,
445+ pub fn snippet_with_applicability < ' a > (
446+ sess : & impl HasSession ,
422447 span : Span ,
423448 default : & ' a str ,
424449 applicability : & mut Applicability ,
425450) -> Cow < ' a , str > {
426- snippet_with_applicability_sess ( cx . sess ( ) , span, default, applicability)
451+ snippet_with_applicability_sess ( sess . sess ( ) , span, default, applicability)
427452}
428453
429454fn snippet_with_applicability_sess < ' a > (
@@ -435,7 +460,7 @@ fn snippet_with_applicability_sess<'a>(
435460 if * applicability != Applicability :: Unspecified && span. from_expansion ( ) {
436461 * applicability = Applicability :: MaybeIncorrect ;
437462 }
438- snippet_opt_sess ( sess, span) . map_or_else (
463+ snippet_opt ( sess, span) . map_or_else (
439464 || {
440465 if * applicability == Applicability :: MachineApplicable {
441466 * applicability = Applicability :: HasPlaceholders ;
@@ -447,12 +472,8 @@ fn snippet_with_applicability_sess<'a>(
447472}
448473
449474/// 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 ( )
456477}
457478
458479/// 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> {
489510/// } // aligned with `if`
490511/// ```
491512/// 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 ,
494515 span : Span ,
495516 default : & ' a str ,
496517 indent_relative_to : Option < Span > ,
497518) -> 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) ) ;
500521 reindent_multiline ( snip, true , indent)
501522}
502523
503524/// Same as `snippet_block`, but adapts the applicability level by the rules of
504525/// `snippet_with_applicability`.
505526pub fn snippet_block_with_applicability < ' a > (
506- cx : & impl LintContext ,
527+ sess : & impl HasSession ,
507528 span : Span ,
508529 default : & ' a str ,
509530 indent_relative_to : Option < Span > ,
510531 applicability : & mut Applicability ,
511532) -> 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) ) ;
514535 reindent_multiline ( snip, true , indent)
515536}
516537
517538pub fn snippet_block_with_context < ' a > (
518- cx : & impl LintContext ,
539+ sess : & impl HasSession ,
519540 span : Span ,
520541 outer : SyntaxContext ,
521542 default : & ' a str ,
522543 indent_relative_to : Option < Span > ,
523544 app : & mut Applicability ,
524545) -> ( 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) ) ;
527548 ( reindent_multiline ( snip, true , indent) , from_macro)
528549}
529550
@@ -537,13 +558,13 @@ pub fn snippet_block_with_context<'a>(
537558///
538559/// This will also return whether or not the snippet is a macro call.
539560pub fn snippet_with_context < ' a > (
540- cx : & impl LintContext ,
561+ sess : & impl HasSession ,
541562 span : Span ,
542563 outer : SyntaxContext ,
543564 default : & ' a str ,
544565 applicability : & mut Applicability ,
545566) -> ( 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)
547568}
548569
549570fn snippet_with_context_sess < ' a > (
@@ -661,15 +682,15 @@ pub fn trim_span(sm: &SourceMap, span: Span) -> Span {
661682/// writeln!(o, "") -> writeln!(o, "")
662683/// ^^ ^^^^
663684/// ```
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 ) ;
666687 extended. with_lo ( extended. lo ( ) - BytePos ( 1 ) )
667688}
668689
669690/// Converts `expr` to a `char` literal if it's a `str` literal containing a single
670691/// character (or a single byte with `ascii_only`)
671692pub fn str_literal_to_char_literal (
672- cx : & LateContext < ' _ > ,
693+ sess : & impl HasSession ,
673694 expr : & Expr < ' _ > ,
674695 applicability : & mut Applicability ,
675696 ascii_only : bool ,
@@ -684,7 +705,7 @@ pub fn str_literal_to_char_literal(
684705 }
685706 && len == 1
686707 {
687- let snip = snippet_with_applicability ( cx , expr. span , string, applicability) ;
708+ let snip = snippet_with_applicability ( sess , expr. span , string, applicability) ;
688709 let ch = if let StrStyle :: Raw ( nhash) = style {
689710 let nhash = nhash as usize ;
690711 // for raw string: r##"a"##
0 commit comments