use hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
use hir::map::Map;
use hir::{GenericArg, GenericParam, ItemLocalId, LifetimeName, ParamName, Node};
-use ty::{self, TyCtxt, GenericParamDefKind};
+use ty::{self, TyCtxt, DefIdTree, GenericParamDefKind};
-use errors::DiagnosticBuilder;
+use errors::{Applicability, DiagnosticBuilder};
use rustc::lint;
use rustc_data_structures::sync::Lrc;
use session::Session;
_ => None,
} {
debug!("id ={:?} span = {:?} name = {:?}", node_id, span, name);
- self.tcx.struct_span_lint_node(
+ let mut err = self.tcx.struct_span_lint_node(
lint::builtin::UNUSED_LIFETIMES,
id,
span,
&format!("lifetime parameter `{}` never used", name)
- ).emit();
+ );
+ if let Some(parent_def_id) = self.tcx.parent(def_id) {
+ if let Some(node_id) = self.tcx.hir.as_local_node_id(parent_def_id) {
+ if let Some(Node::Item(hir_item)) = self.tcx.hir.find(node_id) {
+ match hir_item.node {
+ hir::ItemKind::Fn(_, _, ref generics, _) |
+ hir::ItemKind::Impl(_, _, _, ref generics, _, _, _) => {
+ let unused_lt_span = if generics.params.len() == 1 {
+ // if sole lifetime, remove the `<>` brackets
+ Some(generics.span)
+ } else {
+ generics.params.iter().enumerate()
+ .find_map(|(i, param)| {
+ if param.name.ident() == name {
+ // We also want to delete a leading or
+ // trailing comma as appropriate
+ if i >= generics.params.len() - 1 {
+ Some(
+ generics.params[i-1]
+ .span.shrink_to_hi()
+ .to(param.span)
+ )
+ } else {
+ Some(
+ param.span.to(
+ generics.params[i+1]
+ .span.shrink_to_lo()
+ )
+ )
+ }
+ } else {
+ None
+ }
+ })
+ };
+ if let Some(span) = unused_lt_span {
+ err.span_suggestion_with_applicability(
+ span,
+ "remove it",
+ String::new(),
+ Applicability::MachineApplicable
+ );
+ }
+ },
+ _ => {}
+ }
+ }
+ }
+ }
+ err.emit();
}
}
}
--- /dev/null
+// run-rustfix
+
+// Test that we DO warn when lifetime name is not used at all.
+
+#![deny(unused_lifetimes)]
+#![allow(dead_code, unused_variables)]
+
+fn september() {}
+//~^ ERROR lifetime parameter `'a` never used
+//~| HELP remove it
+
+fn october<'b, T>(s: &'b T) -> &'b T {
+ //~^ ERROR lifetime parameter `'a` never used
+ //~| HELP remove it
+ s
+}
+
+fn november<'a>(s: &'a str) -> (&'a str) {
+ //~^ ERROR lifetime parameter `'b` never used
+ //~| HELP remove it
+ s
+}
+
+fn main() {}
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
+// run-rustfix
// Test that we DO warn when lifetime name is not used at all.
#![deny(unused_lifetimes)]
-#![allow(dead_code)]
-#![allow(unused_variables)]
+#![allow(dead_code, unused_variables)]
-fn d<'a>() { } //~ ERROR `'a` never used
+fn september<'a>() {}
+//~^ ERROR lifetime parameter `'a` never used
+//~| HELP remove it
-fn main() { }
+fn october<'a, 'b, T>(s: &'b T) -> &'b T {
+ //~^ ERROR lifetime parameter `'a` never used
+ //~| HELP remove it
+ s
+}
+
+fn november<'a, 'b>(s: &'a str) -> (&'a str) {
+ //~^ ERROR lifetime parameter `'b` never used
+ //~| HELP remove it
+ s
+}
+
+fn main() {}
error: lifetime parameter `'a` never used
- --> $DIR/zero-uses-in-fn.rs:17:6
+ --> $DIR/zero-uses-in-fn.rs:8:14
|
-LL | fn d<'a>() { } //~ ERROR `'a` never used
- | ^^
+LL | fn september<'a>() {}
+ | -^^- help: remove it
|
note: lint level defined here
- --> $DIR/zero-uses-in-fn.rs:13:9
+ --> $DIR/zero-uses-in-fn.rs:5:9
|
LL | #![deny(unused_lifetimes)]
| ^^^^^^^^^^^^^^^^
-error: aborting due to previous error
+error: lifetime parameter `'a` never used
+ --> $DIR/zero-uses-in-fn.rs:12:12
+ |
+LL | fn october<'a, 'b, T>(s: &'b T) -> &'b T {
+ | ^^--
+ | |
+ | help: remove it
+
+error: lifetime parameter `'b` never used
+ --> $DIR/zero-uses-in-fn.rs:18:17
+ |
+LL | fn november<'a, 'b>(s: &'a str) -> (&'a str) {
+ | --^^
+ | |
+ | help: remove it
+
+error: aborting due to 3 previous errors
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
// Test that we DO warn when lifetime name is not used at all.
#![deny(unused_lifetimes)]
-#![allow(dead_code)]
-#![allow(unused_variables)]
+#![allow(dead_code, unused_variables)]
-struct Foo { }
+struct Foo {}
-impl<'a> Foo { } //~ ERROR `'a` never used
+impl<'a> Foo {} //~ ERROR `'a` never used
-fn main() { }
+fn main() {}
error: lifetime parameter `'a` never used
- --> $DIR/zero-uses-in-impl.rs:19:6
+ --> $DIR/zero-uses-in-impl.rs:8:6
|
-LL | impl<'a> Foo { } //~ ERROR `'a` never used
- | ^^
+LL | impl<'a> Foo {} //~ ERROR `'a` never used
+ | -^^- help: remove it
|
note: lint level defined here
- --> $DIR/zero-uses-in-impl.rs:13:9
+ --> $DIR/zero-uses-in-impl.rs:3:9
|
LL | #![deny(unused_lifetimes)]
| ^^^^^^^^^^^^^^^^