diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2020-01-27 11:48:52 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2020-02-05 10:32:01 -0800 |
| commit | 70dbf5526d37ad031fca57ddde55bf8757bfc326 (patch) | |
| tree | 75d397c532057a49e0202e26964c65d398fa01cf | |
| parent | 183dfac1f31cc16975bb1f598779df5689d1e729 (diff) | |
| download | rust-70dbf5526d37ad031fca57ddde55bf8757bfc326.tar.gz rust-70dbf5526d37ad031fca57ddde55bf8757bfc326.zip | |
Use spans for input borrowed types unrelated to return type
12 files changed, 104 insertions, 25 deletions
diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index a8d6afa0e55..022f83af815 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -287,6 +287,7 @@ struct ElisionFailureInfo { index: usize, lifetime_count: usize, have_bound_regions: bool, + span: Span, } type ScopeRef<'a> = &'a Scope<'a>; @@ -2273,6 +2274,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { index: i, lifetime_count: gather.lifetimes.len(), have_bound_regions: gather.have_bound_regions, + span: input.span, } }) .collect(); @@ -2483,11 +2485,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { params.iter().cloned().filter(|info| info.lifetime_count > 0).collect(); let elided_len = elided_params.len(); + let mut spans = vec![]; - // FIXME: collect spans of the input params when appropriate to use in the diagnostic. for (i, info) in elided_params.into_iter().enumerate() { - let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions } = info; + let ElisionFailureInfo { parent, index, lifetime_count: n, have_bound_regions, span } = info; + spans.push(span); let help_name = if let Some(ident) = parent.and_then(|body| self.tcx.hir().body(body).params[index].pat.simple_ident()) { @@ -2518,14 +2521,22 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } + let help = |msg| { + if spans.is_empty() { + db.help(msg); + } else { + db.span_help(spans, msg); + } + }; + if len == 0 { db.help( "this function's return type contains a borrowed value, \ - but there is no value for it to be borrowed from", + but there is no value for it to be borrowed from", ); self.suggest_lifetime(db, span, "consider giving it a 'static lifetime") } else if elided_len == 0 { - db.help( + help( "this function's return type contains a borrowed value with \ an elided lifetime, but the lifetime cannot be derived from \ the arguments", @@ -2533,16 +2544,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let msg = "consider giving it an explicit bounded or 'static lifetime"; self.suggest_lifetime(db, span, msg) } else if elided_len == 1 { - db.help(&format!( + help(&format!( "this function's return type contains a borrowed value, \ - but the signature does not say which {} it is borrowed from", + but the signature does not say which {} it is borrowed from", m )); true } else { - db.help(&format!( + help(&format!( "this function's return type contains a borrowed value, \ - but the signature does not say whether it is borrowed from {}", + but the signature does not say whether it is borrowed from {}", m )); true diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr index 7e45d588c6c..a12c601b936 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | ) -> &dyn Foo | ^ help: consider using the named lifetime: `&'a` | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` + --> $DIR/issue-63388-2.rs:11:14 + | +LL | foo: &dyn Foo, bar: &'a dyn Foo + | ^^^^^^^^ ^^^^^^^^^^^ error: cannot infer an appropriate lifetime --> $DIR/issue-63388-2.rs:11:9 diff --git a/src/test/ui/issues/issue-19707.stderr b/src/test/ui/issues/issue-19707.stderr index c5129152aa5..1be066caa87 100644 --- a/src/test/ui/issues/issue-19707.stderr +++ b/src/test/ui/issues/issue-19707.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | type Foo = fn(&u8, &u8) -> &u8; | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/issue-19707.rs:3:15 + | +LL | type Foo = fn(&u8, &u8) -> &u8; + | ^^^ ^^^ help: consider introducing a named lifetime parameter | LL | type Foo<'lifetime> = fn(&u8, &u8) -> &'lifetime u8; @@ -16,7 +20,11 @@ error[E0106]: missing lifetime specifier LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {} | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/issue-19707.rs:5:14 + | +LL | fn bar<F: Fn(&u8, &u8) -> &u8>(f: &F) {} + | ^^^ ^^^ = note: for more information on Higher-Ranked lifetimes, visit https://doc.rust-lang.org/nomicon/hrtb.html help: consider introducing a Higher-Ranked lifetime | diff --git a/src/test/ui/issues/issue-26638.stderr b/src/test/ui/issues/issue-26638.stderr index 85d5d9cc42e..882102799d9 100644 --- a/src/test/ui/issues/issue-26638.stderr +++ b/src/test/ui/issues/issue-26638.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() } | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `iter`'s 2 lifetimes it is borrowed from + --> $DIR/issue-26638.rs:1:21 + | +LL | fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider introducing a named lifetime parameter | LL | fn parse_type<'lifetime>(iter: Box<dyn Iterator<Item=&str>+'static>) -> &'lifetime str { iter.next() } diff --git a/src/test/ui/issues/issue-30255.stderr b/src/test/ui/issues/issue-30255.stderr index c9402277640..e2b57a20325 100644 --- a/src/test/ui/issues/issue-30255.stderr +++ b/src/test/ui/issues/issue-30255.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn f(a: &S, b: i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `a`'s 2 lifetimes it is borrowed from + --> $DIR/issue-30255.rs:9:9 + | +LL | fn f(a: &S, b: i32) -> &i32 { + | ^^ help: consider introducing a named lifetime parameter | LL | fn f<'lifetime>(a: &S, b: i32) -> &'lifetime i32 { @@ -16,7 +20,11 @@ error[E0106]: missing lifetime specifier LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from one of `a`'s 2 lifetimes or `c` + --> $DIR/issue-30255.rs:14:9 + | +LL | fn g(a: &S, b: bool, c: &i32) -> &i32 { + | ^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn g<'lifetime>(a: &S, b: bool, c: &i32) -> &'lifetime i32 { @@ -28,7 +36,11 @@ error[E0106]: missing lifetime specifier LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `a`, one of `c`'s 2 lifetimes, or `d` + --> $DIR/issue-30255.rs:19:9 + | +LL | fn h(a: &bool, b: bool, c: &S, d: &i32) -> &i32 { + | ^^^^^ ^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn h<'lifetime>(a: &bool, b: bool, c: &S, d: &i32) -> &'lifetime i32 { diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr index 1d5eeac23f9..d1b597804cd 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-requires-explicit-lifetime.stderr @@ -12,7 +12,11 @@ error[E0106]: missing lifetime specifier LL | fn g(_x: &isize, _y: &isize) -> &isize { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `_x` or `_y` + --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:7:10 + | +LL | fn g(_x: &isize, _y: &isize) -> &isize { + | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | LL | fn g<'lifetime>(_x: &isize, _y: &isize) -> &'lifetime isize { @@ -24,7 +28,11 @@ error[E0106]: missing lifetime specifier LL | fn h(_x: &Foo) -> &isize { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `_x`'s 2 lifetimes it is borrowed from + --> $DIR/lifetime-elision-return-type-requires-explicit-lifetime.rs:17:10 + | +LL | fn h(_x: &Foo) -> &isize { + | ^^^^ help: consider introducing a named lifetime parameter | LL | fn h<'lifetime>(_x: &Foo) -> &'lifetime isize { diff --git a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index 2990ab86824..52a980a61da 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn foo(x: &i32, y: &i32) -> &i32 { | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` + --> $DIR/ex1b-return-no-names-if-else.rs:1:11 + | +LL | fn foo(x: &i32, y: &i32) -> &i32 { + | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn foo<'lifetime>(x: &i32, y: &i32) -> &'lifetime i32 { diff --git a/src/test/ui/rfc1623.stderr b/src/test/ui/rfc1623.stderr index 5b665e18141..aabe088d63c 100644 --- a/src/test/ui/rfc1623.stderr +++ b/src/test/ui/rfc1623.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/rfc1623.rs:8:29 + | +LL | static NON_ELIDABLE_FN: &fn(&u8, &u8) -> &u8 = + | ^^^ ^^^ error[E0106]: missing lifetime specifier --> $DIR/rfc1623.rs:10:39 @@ -12,7 +16,11 @@ error[E0106]: missing lifetime specifier LL | &(non_elidable as fn(&u8, &u8) -> &u8); | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/rfc1623.rs:10:26 + | +LL | &(non_elidable as fn(&u8, &u8) -> &u8); + | ^^^ ^^^ error: aborting due to 2 previous errors diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 7f5ff95938e..3b7936c5f44 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -10,7 +10,11 @@ error[E0106]: missing lifetime specifier LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + --> $DIR/return-without-lifetime.rs:5:20 + | +LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } + | ^^^^^^^^^ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:7:35 @@ -18,7 +22,11 @@ error[E0106]: missing lifetime specifier LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` | - = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from +help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + --> $DIR/return-without-lifetime.rs:7:20 + | +LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } + | ^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr index 0a028e44919..1e15196f8ec 100644 --- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-lifetime-elision.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | let _: dyn Foo(&isize, &usize) -> &usize; | ^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or argument 2 + --> $DIR/unboxed-closure-sugar-lifetime-elision.rs:26:20 + | +LL | let _: dyn Foo(&isize, &usize) -> &usize; + | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | LL | fn main<'lifetime>() { diff --git a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr index cf820249c80..801504627c0 100644 --- a/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr +++ b/src/test/ui/underscore-lifetime/in-fn-return-illegal.stderr @@ -4,7 +4,11 @@ error[E0106]: missing lifetime specifier LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } | ^^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `x` or `y` + --> $DIR/in-fn-return-illegal.rs:5:11 + | +LL | fn foo(x: &u32, y: &u32) -> &'_ u32 { loop { } } + | ^^^^ ^^^^ help: consider introducing a named lifetime parameter | LL | fn foo<'lifetime>(x: &u32, y: &u32) -> &'lifetime u32 { loop { } } diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr index 517904ee628..ef3ad18ee88 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -30,7 +30,11 @@ error[E0106]: missing lifetime specifier LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } | ^^ expected named lifetime parameter | - = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` +help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from argument 1 or `y` + --> $DIR/underscore-lifetime-binders.rs:16:12 + | +LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } + | ^^^^^^ ^^^^^^ help: consider introducing a named lifetime parameter | LL | fn foo2<'lifetime>(_: &'_ u8, y: &'_ u8) -> &'lifetime u8 { y } |
