Skip to content

Commit

Permalink
Auto merge of #50440 - nikomatsakis:single-use-lifetimes, r=cramertj
Browse files Browse the repository at this point in the history
Improve single-use and zero-use lifetime lints

The code now correctly identifies *when* to lint -- or more correctly, anyhow -- but it doesn't yet offer suggestions for how to fix.

(I just remembered when writing this I had meant to go back over some of these cases around e.g. impl Trait and double check that everything is right...)

cc #44752

r? @cramertj
  • Loading branch information
bors committed May 11, 2018
2 parents a006328 + 6f98ee9 commit 4e5a155
Show file tree
Hide file tree
Showing 33 changed files with 728 additions and 169 deletions.
9 changes: 8 additions & 1 deletion src/librustc/lint/builtin.rs
Expand Up @@ -233,7 +233,13 @@ declare_lint! {
declare_lint! {
pub SINGLE_USE_LIFETIME,
Allow,
"detects single use lifetimes"
"detects lifetime parameters that are only used once"
}

declare_lint! {
pub UNUSED_LIFETIME,
Allow,
"detects lifetime parameters that are never used"
}

declare_lint! {
Expand Down Expand Up @@ -318,6 +324,7 @@ impl LintPass for HardwiredLints {
UNUSED_UNSAFE,
UNUSED_MUT,
SINGLE_USE_LIFETIME,
UNUSED_LIFETIME,
TYVAR_BEHIND_RAW_POINTER,
ELIDED_LIFETIME_IN_PATH,
BARE_TRAIT_OBJECT,
Expand Down
260 changes: 200 additions & 60 deletions src/librustc/middle/resolve_lifetime.rs

Large diffs are not rendered by default.

14 changes: 0 additions & 14 deletions src/test/ui/in-band-lifetimes/single_use_lifetimes-2.stderr

This file was deleted.

20 changes: 0 additions & 20 deletions src/test/ui/in-band-lifetimes/single_use_lifetimes-3.stderr

This file was deleted.

20 changes: 0 additions & 20 deletions src/test/ui/in-band-lifetimes/single_use_lifetimes-4.stderr

This file was deleted.

14 changes: 0 additions & 14 deletions src/test/ui/in-band-lifetimes/single_use_lifetimes-5.stderr

This file was deleted.

14 changes: 0 additions & 14 deletions src/test/ui/in-band-lifetimes/single_use_lifetimes.stderr

This file was deleted.

26 changes: 26 additions & 0 deletions src/test/ui/single-use-lifetime/fn-types.rs
@@ -0,0 +1,26 @@
// 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.

#![deny(single_use_lifetime)]
#![allow(dead_code)]
#![allow(unused_variables)]

// Test that we DO warn when lifetime name is used only
// once in a fn argument.

struct Foo {
a: for<'a> fn(&'a u32), //~ ERROR `'a` only used once
b: for<'a> fn(&'a u32, &'a u32), // OK, used twice.
c: for<'a> fn(&'a u32) -> &'a u32, // OK, used twice.
d: for<'a> fn() -> &'a u32, // OK, used only in return type.
//~^ ERROR return type references lifetime `'a`, which is not constrained by the fn input types
}

fn main() { }
21 changes: 21 additions & 0 deletions src/test/ui/single-use-lifetime/fn-types.stderr
@@ -0,0 +1,21 @@
error: lifetime parameter `'a` only used once
--> $DIR/fn-types.rs:19:10
|
LL | a: for<'a> fn(&'a u32), //~ ERROR `'a` only used once
| ^^
|
note: lint level defined here
--> $DIR/fn-types.rs:11:9
|
LL | #![deny(single_use_lifetime)]
| ^^^^^^^^^^^^^^^^^^^

error[E0581]: return type references lifetime `'a`, which is not constrained by the fn input types
--> $DIR/fn-types.rs:22:22
|
LL | d: for<'a> fn() -> &'a u32, // OK, used only in return type.
| ^^^^^^^

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0581`.
24 changes: 24 additions & 0 deletions src/test/ui/single-use-lifetime/one-use-in-fn-argument-in-band.rs
@@ -0,0 +1,24 @@
// 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.

#![feature(in_band_lifetimes)]
#![deny(single_use_lifetime)]
#![allow(dead_code)]
#![allow(unused_variables)]

// Test that we DO warn when lifetime name is used only
// once in a fn argument, even with in band lifetimes.

fn a(x: &'a u32, y: &'b u32) {
//~^ ERROR `'a` only used once
//~| ERROR `'b` only used once
}

fn main() { }
@@ -0,0 +1,20 @@
error: lifetime parameter `'b` only used once
--> $DIR/one-use-in-fn-argument-in-band.rs:19:22
|
LL | fn a(x: &'a u32, y: &'b u32) {
| ^^
|
note: lint level defined here
--> $DIR/one-use-in-fn-argument-in-band.rs:12:9
|
LL | #![deny(single_use_lifetime)]
| ^^^^^^^^^^^^^^^^^^^

error: lifetime parameter `'a` only used once
--> $DIR/one-use-in-fn-argument-in-band.rs:19:10
|
LL | fn a(x: &'a u32, y: &'b u32) {
| ^^

error: aborting due to 2 previous errors

@@ -1,4 +1,4 @@
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
// 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.
//
Expand All @@ -7,10 +7,15 @@
// <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.

#![deny(single_use_lifetime)]
// FIXME(#44752) -- this scenario should not be warned
fn deref<'x>() -> &'x u32 { //~ ERROR lifetime name `'x` only used once
22
#![allow(dead_code)]
#![allow(unused_variables)]

// Test that we DO warn when lifetime name is used only
// once in a fn argument.

fn a<'a>(x: &'a u32) { //~ ERROR `'a` only used once
}

fn main() { }
14 changes: 14 additions & 0 deletions src/test/ui/single-use-lifetime/one-use-in-fn-argument.stderr
@@ -0,0 +1,14 @@
error: lifetime parameter `'a` only used once
--> $DIR/one-use-in-fn-argument.rs:18:6
|
LL | fn a<'a>(x: &'a u32) { //~ ERROR `'a` only used once
| ^^
|
note: lint level defined here
--> $DIR/one-use-in-fn-argument.rs:11:9
|
LL | #![deny(single_use_lifetime)]
| ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

30 changes: 30 additions & 0 deletions src/test/ui/single-use-lifetime/one-use-in-fn-return.rs
@@ -0,0 +1,30 @@
// 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.

// compile-pass

#![deny(single_use_lifetime)]
#![allow(dead_code)]
#![allow(unused_variables)]

// Test that we DO NOT warn when lifetime name is used only
// once in a fn return type -- using `'_` is not legal there,
// as it must refer back to an argument.
//
// (Normally, using `'static` would be preferred, but there are
// times when that is not what you want.)
//
// run-pass

fn b<'a>() -> &'a u32 { // OK: used only in return type
&22
}

fn main() { }
29 changes: 29 additions & 0 deletions src/test/ui/single-use-lifetime/one-use-in-inherent-impl-header.rs
@@ -0,0 +1,29 @@
// 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.

#![deny(single_use_lifetime)]
#![allow(dead_code)]
#![allow(unused_variables)]

// Test that we DO warn for a lifetime used only once in an impl.
//
// (Actually, until #15872 is fixed, you can't use `'_` here, but
// hopefully that will come soon.)

struct Foo<'f> {
data: &'f u32
}

impl<'f> Foo<'f> { //~ ERROR `'f` only used once
fn inherent_a(&self) {
}
}

fn main() { }
@@ -0,0 +1,14 @@
error: lifetime parameter `'f` only used once
--> $DIR/one-use-in-inherent-impl-header.rs:24:6
|
LL | impl<'f> Foo<'f> { //~ ERROR `'f` only used once
| ^^
|
note: lint level defined here
--> $DIR/one-use-in-inherent-impl-header.rs:11:9
|
LL | #![deny(single_use_lifetime)]
| ^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

@@ -0,0 +1,26 @@
// 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.

#![deny(single_use_lifetime)]
#![allow(dead_code)]
#![allow(unused_variables)]

// Test that we DO warn for a lifetime used only once in an inherent method.

struct Foo<'f> {
data: &'f u32
}

impl<'f> Foo<'f> { //~ ERROR `'f` only used once
fn inherent_a<'a>(&self, data: &'a u32) { //~ ERROR `'a` only used once
}
}

fn main() { }
@@ -0,0 +1,20 @@
error: lifetime parameter `'a` only used once
--> $DIR/one-use-in-inherent-method-argument.rs:22:19
|
LL | fn inherent_a<'a>(&self, data: &'a u32) { //~ ERROR `'a` only used once
| ^^
|
note: lint level defined here
--> $DIR/one-use-in-inherent-method-argument.rs:11:9
|
LL | #![deny(single_use_lifetime)]
| ^^^^^^^^^^^^^^^^^^^

error: lifetime parameter `'f` only used once
--> $DIR/one-use-in-inherent-method-argument.rs:21:6
|
LL | impl<'f> Foo<'f> { //~ ERROR `'f` only used once
| ^^

error: aborting due to 2 previous errors

@@ -0,0 +1,28 @@
// 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.

#![deny(single_use_lifetime)]
#![allow(dead_code)]
#![allow(unused_variables)]

// Test that we DO NOT warn for a lifetime used just once in a return type,
// where that return type is in an inherent method.

struct Foo<'f> {
data: &'f u32
}

impl<'f> Foo<'f> { //~ ERROR `'f` only used once
fn inherent_a<'a>(&self) -> &'a u32 { // OK for 'a
&22
}
}

fn main() { }

0 comments on commit 4e5a155

Please sign in to comment.