Skip to content

Commit 3c22b23

Browse files
committed
Merge remote-tracking branch 'upstream/master'
2 parents f4b919c + 6a165e5 commit 3c22b23

39 files changed

+996
-717
lines changed

.travis.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ matrix:
6363
- env: INTEGRATION=chronotope/chrono
6464
- env: INTEGRATION=serde-rs/serde
6565
- env: INTEGRATION=Geal/nom
66-
# uncomment once https://github.com/rust-lang/rust/issues/55376 is fixed
67-
# - env: INTEGRATION=hyperium/hyper
66+
- env: INTEGRATION=hyperium/hyper
6867
allow_failures:
6968
- os: windows
7069
env: BASE_TEST=true

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ rustc_tools_util = { version = "0.1.0", path = "rustc_tools_util"}
4848
[dev-dependencies]
4949
clippy_dev = { version = "0.0.1", path = "clippy_dev" }
5050
cargo_metadata = "0.6"
51-
compiletest_rs = "0.3.7"
51+
compiletest_rs = "0.3.16"
5252
lazy_static = "1.0"
5353
serde_derive = "1.0"
5454
clippy-mini-macro-test = { version = "0.2", path = "mini-macro" }

ci/base-tests.sh

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,21 +24,20 @@ cd clippy_lints && cargo test && cd ..
2424
cd rustc_tools_util && cargo test && cd ..
2525
# check that the lint lists are up-to-date
2626
./util/update_lints.py -c
27-
mkdir -p ~/rust/cargo/bin
28-
cp target/debug/cargo-clippy ~/rust/cargo/bin/cargo-clippy
29-
cp target/debug/clippy-driver ~/rust/cargo/bin/clippy-driver
30-
rm ~/.cargo/bin/cargo-clippy
27+
28+
CLIPPY="`pwd`/target/debug/cargo-clippy clippy"
3129
# run clippy on its own codebase...
32-
PATH=$PATH:~/rust/cargo/bin cargo clippy --all-targets --all-features -- -D clippy::all -D clippy::internal
30+
${CLIPPY} --all-targets --all-features -- -D clippy::all -D clippy::internal
3331
# ... and some test directories
34-
cd clippy_workspace_tests && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ..
35-
cd clippy_workspace_tests/src && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ../..
36-
cd clippy_workspace_tests/subcrate && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ../..
37-
cd clippy_workspace_tests/subcrate/src && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ../../..
38-
cd clippy_dev && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ..
39-
cd rustc_tools_util/ && PATH=$PATH:~/rust/cargo/bin cargo clippy -- -D clippy::all && cd ..
32+
for dir in clippy_workspace_tests clippy_workspace_tests/src clippy_workspace_tests/subcrate clippy_workspace_tests/subcrate/src clippy_dev rustc_tools_util
33+
do
34+
cd ${dir}
35+
${CLIPPY} -- -D clippy::all
36+
cd -
37+
done
38+
4039

4140
# test --manifest-path
42-
PATH=$PATH:~/rust/cargo/bin cargo clippy --manifest-path=clippy_workspace_tests/Cargo.toml -- -D clippy::all
43-
cd clippy_workspace_tests/subcrate && PATH=$PATH:~/rust/cargo/bin cargo clippy --manifest-path=../Cargo.toml -- -D clippy::all && cd ../..
41+
${CLIPPY} --manifest-path=clippy_workspace_tests/Cargo.toml -- -D clippy::all
42+
cd clippy_workspace_tests/subcrate && ${CLIPPY} --manifest-path=../Cargo.toml -- -D clippy::all && cd ../..
4443
set +x

ci/integration-tests.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,6 @@ function check() {
2828
}
2929

3030
case ${INTEGRATION} in
31-
rust-lang/cargo)
32-
check
33-
;;
3431
*)
3532
check
3633
;;

clippy_lints/src/identity_conversion.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
1212
use crate::rustc::{declare_tool_lint, lint_array};
1313
use crate::rustc::hir::*;
1414
use crate::syntax::ast::NodeId;
15-
use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, span_lint_and_then};
15+
use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, snippet_with_macro_callsite, span_lint_and_then};
1616
use crate::utils::{opt_def_id, paths, resolve_node};
1717
use crate::rustc_errors::Applicability;
1818

@@ -72,7 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion {
7272
let a = cx.tables.expr_ty(e);
7373
let b = cx.tables.expr_ty(&args[0]);
7474
if same_tys(cx, a, b) {
75-
let sugg = snippet(cx, args[0].span, "<expr>").into_owned();
75+
let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string();
76+
7677
span_lint_and_then(cx, IDENTITY_CONVERSION, e.span, "identical conversion", |db| {
7778
db.span_suggestion_with_applicability(
7879
e.span,

clippy_lints/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ use toml;
4848

4949
// Currently, categories "style", "correctness", "complexity" and "perf" are enabled by default,
5050
// as said in the README.md of this repository. If this changes, please update README.md.
51+
#[macro_export]
5152
macro_rules! declare_clippy_lint {
5253
{ pub $name:tt, style, $description:tt } => {
5354
declare_tool_lint! { pub clippy::$name, Warn, $description, report_in_external_macro: true }

clippy_lints/src/matches.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ use crate::syntax::ast::LitKind;
1919
use crate::syntax::source_map::Span;
2020
use crate::utils::paths;
2121
use crate::utils::{expr_block, is_allowed, is_expn_of, match_qpath, match_type, multispan_sugg,
22-
remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty};
22+
remove_blocks, snippet, span_lint_and_sugg, span_lint_and_then,
23+
span_note_and_lint, walk_ptrs_ty};
2324
use crate::utils::sugg::Sugg;
2425
use crate::consts::{constant, Constant};
2526
use crate::rustc_errors::Applicability;

clippy_lints/src/methods/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use crate::utils::sugg;
2121
use crate::utils::{
2222
get_arg_name, get_trait_def_id, implements_trait, in_macro, is_copy, is_expn_of, is_self, is_self_ty,
2323
iter_input_pats, last_path_segment, match_def_path, match_path, match_qpath, match_trait_method, match_type,
24-
match_var, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, span_lint,
24+
match_var, method_chain_args, remove_blocks, return_ty, same_tys, single_segment_path, snippet, snippet_with_macro_callsite, span_lint,
2525
span_lint_and_sugg, span_lint_and_then, span_note_and_lint, walk_ptrs_ty, walk_ptrs_ty_depth, SpanlessEq,
2626
};
2727
use if_chain::if_chain;
@@ -568,7 +568,14 @@ declare_clippy_lint! {
568568
/// **Why is this bad?** Using the Index trait (`[]`) is more clear and more
569569
/// concise.
570570
///
571-
/// **Known problems:** None.
571+
/// **Known problems:** Not a replacement for error handling: Using either
572+
/// `.unwrap()` or the Index trait (`[]`) carries the risk of causing a `panic`
573+
/// if the value being accessed is `None`. If the use of `.get().unwrap()` is a
574+
/// temporary placeholder for dealing with the `Option` type, then this does
575+
/// not mitigate the need for error handling. If there is a chance that `.get()`
576+
/// will be `None` in your program, then it is advisable that the `None` case
577+
/// is handled in a future refactor instead of using `.unwrap()` or the Index
578+
/// trait.
572579
///
573580
/// **Example:**
574581
/// ```rust
@@ -1062,9 +1069,9 @@ fn lint_or_fun_call(cx: &LateContext<'_, '_>, expr: &hir::Expr, method_span: Spa
10621069
}
10631070

10641071
let sugg: Cow<'_, _> = match (fn_has_arguments, !or_has_args) {
1065-
(true, _) => format!("|_| {}", snippet(cx, arg.span, "..")).into(),
1066-
(false, false) => format!("|| {}", snippet(cx, arg.span, "..")).into(),
1067-
(false, true) => snippet(cx, fun_span, ".."),
1072+
(true, _) => format!("|_| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
1073+
(false, false) => format!("|| {}", snippet_with_macro_callsite(cx, arg.span, "..")).into(),
1074+
(false, true) => snippet_with_macro_callsite(cx, fun_span, ".."),
10681075
};
10691076
let span_replace_word = method_span.with_hi(span.hi());
10701077
span_lint_and_sugg(

clippy_lints/src/needless_bool.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::rustc::{declare_tool_lint, lint_array};
1717
use crate::rustc::hir::*;
1818
use crate::syntax::ast::LitKind;
1919
use crate::syntax::source_map::Spanned;
20-
use crate::utils::{snippet, span_lint, span_lint_and_sugg};
20+
use crate::utils::{in_macro, snippet, span_lint, span_lint_and_sugg};
2121
use crate::utils::sugg::Sugg;
2222

2323
/// **What it does:** Checks for expressions of the form `if c { true } else {
@@ -133,6 +133,9 @@ impl LintPass for BoolComparison {
133133

134134
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for BoolComparison {
135135
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
136+
if in_macro(e.span) {
137+
return;
138+
}
136139
use self::Expression::*;
137140
if let ExprKind::Binary(Spanned { node: BinOpKind::Eq, .. }, ref left_side, ref right_side) = e.node {
138141
match (fetch_bool_expr(left_side), fetch_bool_expr(right_side)) {

clippy_lints/src/redundant_clone.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::rustc::hir::{def_id, Body, FnDecl};
1212
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
1313
use crate::rustc::mir::{
1414
self, traversal,
15-
visit::{PlaceContext, Visitor},
15+
visit::{MutatingUseContext, NonUseContext, PlaceContext, Visitor},
1616
TerminatorKind,
1717
};
1818
use crate::rustc::ty;
@@ -279,7 +279,7 @@ impl<'tcx> mir::visit::Visitor<'tcx> for LocalUseVisitor {
279279

280280
fn visit_local(&mut self, local: &mir::Local, ctx: PlaceContext<'tcx>, _: mir::Location) {
281281
match ctx {
282-
PlaceContext::Drop | PlaceContext::StorageDead => return,
282+
PlaceContext::MutatingUse(MutatingUseContext::Drop) | PlaceContext::NonUse(NonUseContext::StorageDead) => return,
283283
_ => {},
284284
}
285285

clippy_lints/src/strings.rs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
// option. This file may not be copied, modified, or distributed
88
// except according to those terms.
99

10-
1110
use crate::rustc::hir::*;
1211
use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
1312
use crate::rustc::{declare_tool_lint, lint_array};
@@ -92,7 +91,14 @@ impl LintPass for StringAdd {
9291

9392
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringAdd {
9493
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
95-
if let ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) = e.node {
94+
if let ExprKind::Binary(
95+
Spanned {
96+
node: BinOpKind::Add, ..
97+
},
98+
ref left,
99+
_,
100+
) = e.node
101+
{
96102
if is_string(cx, left) {
97103
if !is_allowed(cx, STRING_ADD_ASSIGN, e.id) {
98104
let parent = get_parent_expr(cx, e);
@@ -132,13 +138,15 @@ fn is_string(cx: &LateContext<'_, '_>, e: &Expr) -> bool {
132138

133139
fn is_add(cx: &LateContext<'_, '_>, src: &Expr, target: &Expr) -> bool {
134140
match src.node {
135-
ExprKind::Binary(Spanned { node: BinOpKind::Add, .. }, ref left, _) => SpanlessEq::new(cx).eq_expr(target, left),
141+
ExprKind::Binary(
142+
Spanned {
143+
node: BinOpKind::Add, ..
144+
},
145+
ref left,
146+
_,
147+
) => SpanlessEq::new(cx).eq_expr(target, left),
136148
ExprKind::Block(ref block, _) => {
137-
block.stmts.is_empty()
138-
&& block
139-
.expr
140-
.as_ref()
141-
.map_or(false, |expr| is_add(cx, expr, target))
149+
block.stmts.is_empty() && block.expr.as_ref().map_or(false, |expr| is_add(cx, expr, target))
142150
},
143151
_ => false,
144152
}
@@ -155,14 +163,33 @@ impl LintPass for StringLitAsBytes {
155163

156164
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for StringLitAsBytes {
157165
fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx Expr) {
158-
use crate::syntax::ast::LitKind;
166+
use crate::syntax::ast::{LitKind, StrStyle};
159167
use crate::utils::{in_macro, snippet};
160168

161169
if let ExprKind::MethodCall(ref path, _, ref args) = e.node {
162170
if path.ident.name == "as_bytes" {
163171
if let ExprKind::Lit(ref lit) = args[0].node {
164-
if let LitKind::Str(ref lit_content, _) = lit.node {
165-
if lit_content.as_str().chars().all(|c| c.is_ascii()) && !in_macro(args[0].span) {
172+
if let LitKind::Str(ref lit_content, style) = lit.node {
173+
let callsite = snippet(cx, args[0].span.source_callsite(), r#""foo""#);
174+
let expanded = if let StrStyle::Raw(n) = style {
175+
let term = (0..n).map(|_| '#').collect::<String>();
176+
format!("r{0}\"{1}\"{0}", term, lit_content.as_str())
177+
} else {
178+
format!("\"{}\"", lit_content.as_str())
179+
};
180+
if callsite.starts_with("include_str!") {
181+
span_lint_and_sugg(
182+
cx,
183+
STRING_LIT_AS_BYTES,
184+
e.span,
185+
"calling `as_bytes()` on `include_str!(..)`",
186+
"consider using `include_bytes!(..)` instead",
187+
snippet(cx, args[0].span, r#""foo""#).replacen("include_str", "include_bytes", 1),
188+
);
189+
} else if callsite == expanded
190+
&& lit_content.as_str().chars().all(|c| c.is_ascii())
191+
&& !in_macro(args[0].span)
192+
{
166193
span_lint_and_sugg(
167194
cx,
168195
STRING_LIT_AS_BYTES,

clippy_lints/src/use_self.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use crate::syntax_pos::symbol::keywords::SelfType;
3636
/// }
3737
/// ```
3838
/// could be
39-
/// ```
39+
/// ```rust
4040
/// struct Foo {}
4141
/// impl Foo {
4242
/// fn new() -> Self {

clippy_lints/src/utils/internal_lints.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@
99

1010

1111
use crate::utils::{
12-
match_qpath, match_type, paths, span_help_and_lint, span_lint, span_lint_and_sugg, walk_ptrs_ty,
12+
match_def_path, match_type, paths, span_help_and_lint, span_lint, span_lint_and_sugg, walk_ptrs_ty,
1313
};
1414
use if_chain::if_chain;
1515
use crate::rustc::hir;
1616
use crate::rustc::hir::intravisit::{walk_expr, NestedVisitorMap, Visitor};
1717
use crate::rustc::hir::*;
18+
use crate::rustc::hir::def::Def;
1819
use crate::rustc::lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintArray, LintPass};
1920
use crate::rustc::{declare_tool_lint, lint_array};
2021
use crate::rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -160,15 +161,21 @@ impl LintPass for LintWithoutLintPass {
160161

161162
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
162163
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) {
163-
if let hir::ItemKind::Static(ref ty, MutImmutable, body_id) = item.node {
164-
if is_lint_ref_type(ty) {
164+
if let hir::ItemKind::Static(ref ty, MutImmutable, _) = item.node {
165+
if is_lint_ref_type(cx, ty) {
165166
self.declared_lints.insert(item.name, item.span);
166-
} else if is_lint_array_type(ty) && item.name == "ARRAY" {
167-
if let VisibilityKind::Inherited = item.vis.node {
167+
}
168+
} else if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.node {
169+
if_chain! {
170+
if let hir::TraitRef{path, ..} = trait_ref;
171+
if let Def::Trait(def_id) = path.def;
172+
if match_def_path(cx.tcx, def_id, &paths::LINT_PASS);
173+
then {
168174
let mut collector = LintCollector {
169175
output: &mut self.registered_lints,
170176
cx,
171177
};
178+
let body_id = cx.tcx.hir.body_owned_by(impl_item_refs[0].id.node_id);
172179
collector.visit_expr(&cx.tcx.hir.body(body_id).value);
173180
}
174181
}
@@ -203,28 +210,22 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for LintWithoutLintPass {
203210
}
204211
}
205212

206-
fn is_lint_ref_type(ty: &Ty) -> bool {
213+
fn is_lint_ref_type<'tcx>(cx: &LateContext<'_, 'tcx>, ty: &Ty) -> bool {
207214
if let TyKind::Rptr(
208215
_,
209216
MutTy {
210217
ty: ref inner,
211218
mutbl: MutImmutable,
212219
},
213-
) = ty.node
214-
{
220+
) = ty.node {
215221
if let TyKind::Path(ref path) = inner.node {
216-
return match_qpath(path, &paths::LINT);
222+
if let Def::Struct(def_id) = cx.tables.qpath_def(path, inner.hir_id) {
223+
return match_def_path(cx.tcx, def_id, &paths::LINT);
224+
}
217225
}
218226
}
219-
false
220-
}
221227

222-
fn is_lint_array_type(ty: &Ty) -> bool {
223-
if let TyKind::Path(ref path) = ty.node {
224-
match_qpath(path, &paths::LINT_ARRAY)
225-
} else {
226-
false
227-
}
228+
false
228229
}
229230

230231
struct LintCollector<'a, 'tcx: 'a> {

clippy_lints/src/utils/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,12 @@ pub fn snippet<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str)
362362
snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from)
363363
}
364364

365+
/// Same as `snippet`, but should only be used when it's clear that the input span is
366+
/// not a macro argument.
367+
pub fn snippet_with_macro_callsite<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> {
368+
snippet(cx, span.source_callsite(), default)
369+
}
370+
365371
/// Convert a span to a code snippet. Returns `None` if not available.
366372
pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> {
367373
cx.sess().source_map().span_to_snippet(span).ok()
@@ -386,7 +392,7 @@ pub fn snippet_block<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'
386392
pub fn last_line_of_span<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Span {
387393
let file_map_and_line = cx.sess().source_map().lookup_line(span.lo()).unwrap();
388394
let line_no = file_map_and_line.line;
389-
let line_start = &file_map_and_line.fm.lines[line_no];
395+
let line_start = &file_map_and_line.sf.lines[line_no];
390396
Span::new(*line_start, span.hi(), span.ctxt())
391397
}
392398

@@ -400,7 +406,10 @@ pub fn expr_block<'a, 'b, T: LintContext<'b>>(
400406
) -> Cow<'a, str> {
401407
let code = snippet_block(cx, expr.span, default);
402408
let string = option.unwrap_or_default();
403-
if let ExprKind::Block(_, _) = expr.node {
409+
if in_macro(expr.span) {
410+
Cow::Owned(format!("{{ {} }}", snippet_with_macro_callsite(cx, expr.span, default)))
411+
}
412+
else if let ExprKind::Block(_, _) = expr.node {
404413
Cow::Owned(format!("{}{}", code, string))
405414
} else if string.is_empty() {
406415
Cow::Owned(format!("{{ {} }}", code))

clippy_lints/src/utils/paths.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ pub const ITERATOR: [&str; 4] = ["core", "iter", "iterator", "Iterator"];
5656
pub const LATE_CONTEXT: [&str; 4] = ["rustc", "lint", "context", "LateContext"];
5757
pub const LINKED_LIST: [&str; 4] = ["alloc", "collections", "linked_list", "LinkedList"];
5858
pub const LINT: [&str; 3] = ["rustc", "lint", "Lint"];
59-
pub const LINT_ARRAY: [&str; 3] = ["rustc", "lint", "LintArray"];
59+
pub const LINT_PASS: [&str; 3] = ["rustc", "lint", "LintPass"];
6060
pub const MEM_DISCRIMINANT: [&str; 3] = ["core", "mem", "discriminant"];
6161
pub const MEM_FORGET: [&str; 3] = ["core", "mem", "forget"];
6262
pub const MEM_REPLACE: [&str; 3] = ["core", "mem", "replace"];

clippy_lints/src/utils/sugg.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,7 @@ impl<'a, 'b, 'c, T: LintContext<'c>> DiagnosticBuilderExt<'c, T> for rustc_error
548548
let hi = cx.sess().source_map().next_point(remove_span).hi();
549549
let fmpos = cx.sess().source_map().lookup_byte_offset(hi);
550550

551-
if let Some(ref src) = fmpos.fm.src {
551+
if let Some(ref src) = fmpos.sf.src {
552552
let non_whitespace_offset = src[fmpos.pos.to_usize()..].find(|c| c != ' ' && c != '\t' && c != '\n');
553553

554554
if let Some(non_whitespace_offset) = non_whitespace_offset {

0 commit comments

Comments
 (0)