Skip to content

Commit

Permalink
Improve output of argument anonymous borrow missing annotation involv…
Browse files Browse the repository at this point in the history
…ing opaque return type

Go from

```
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
  --> file8.rs:22:5
   |
22 | /     move || {
23 | |         *dest = g.get();
24 | |     }
   | |_____^
   |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 18:1...
  --> file8.rs:18:1
   |
18 | / fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
19 | | where
20 | |     G: Get<T>
21 | | {
...  |
24 | |     }
25 | | }
   | |_^
note: ...so that the types are compatible
  --> file8.rs:22:5
   |
22 | /     move || { //~ ERROR cannot infer an appropriate lifetime
23 | |         *dest = g.get();
24 | |     }
   | |_____^
   = note: expected  `&mut T`
              found  `&mut T`
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 18:8...
  --> file8.rs:18:8
   |
18 | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
   |        ^^
note: ...so that return value is valid for the call
  --> file8.rs:18:45
   |
18 | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
   |                                             ^^^^^^^^^^^^^^^^^^^^^^^
```

to

```
error[E0621]: explicit lifetime required in the type of `dest`
  --> file8.rs:18:45
   |
18 | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
   |                                  ------     ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
   |                                  |
   |                                  help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`
   ```
  • Loading branch information
estebank committed May 30, 2020
1 parent f49ebbb commit 99d9ccd
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 76 deletions.
11 changes: 6 additions & 5 deletions src/librustc_infer/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1917,14 +1917,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
"...",
);

debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);

if let (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) =
(&sup_origin, &sub_origin)
{
debug!("report_sub_sup_conflict: var_origin={:?}", var_origin);
debug!("report_sub_sup_conflict: sub_region={:?}", sub_region);
debug!("report_sub_sup_conflict: sub_origin={:?}", sub_origin);
debug!("report_sub_sup_conflict: sup_region={:?}", sup_region);
debug!("report_sub_sup_conflict: sup_origin={:?}", sup_origin);
debug!("report_sub_sup_conflict: sup_trace={:?}", sup_trace);
debug!("report_sub_sup_conflict: sub_trace={:?}", sub_trace);
debug!("report_sub_sup_conflict: sup_trace.values={:?}", sup_trace.values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,22 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}

if let Some((_, fndecl)) = self.find_anon_type(anon, &br) {
if self.is_return_type_anon(scope_def_id, br, fndecl).is_some()
|| self.is_self_anon(is_first, scope_def_id)
{
let return_type_anon = self.is_return_type_anon(scope_def_id, br, fndecl);
let is_self_anon = self.is_self_anon(is_first, scope_def_id);
debug!(
"try_report_named_anon_conflict: fndecl {:?} {:?} {}",
fndecl, return_type_anon, is_self_anon
);
if is_self_anon {
// We used to check for `return_type_anon.is_some()` here. Removing that improves
// some diagnostics, but we might have to readd the check if there are regressions
// in the wild.
return None;
}
if let FnRetTy::Return(ty) = &fndecl.output {
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.kind, sub) {
debug!("try_report_named_anon_conflict: impl Trait + 'static");
// This is an impl Trait return that evaluates de need of 'static.
// We handle this case better in `static_impl_trait`.
return None;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ where
}

// After applying suggestion for `qux`:
// FIXME: we should suggest be suggesting to change `dest` to `&'a mut T`.
fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
//~^ ERROR explicit lifetime required in the type of `dest`
where
G: Get<T>
{
move || { //~ ERROR cannot infer an appropriate lifetime
move || {
*dest = g.get();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,44 +87,13 @@ help: consider introducing an explicit lifetime bound to unify the type paramete
LL | fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'b
| ^^^ ^^^^^^^ ^^^^

error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> $DIR/missing-lifetimes-in-signature.rs:63:5
|
LL | / move || {
LL | | *dest = g.get();
LL | | }
| |_____^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 59:1...
--> $DIR/missing-lifetimes-in-signature.rs:59:1
|
LL | / fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
LL | | where
LL | | G: Get<T>
LL | | {
... |
LL | | }
LL | | }
| |_^
note: ...so that the types are compatible
--> $DIR/missing-lifetimes-in-signature.rs:63:5
|
LL | / move || {
LL | | *dest = g.get();
LL | | }
| |_____^
= note: expected `&mut T`
found `&mut T`
note: but, the lifetime must be valid for the lifetime `'a` as defined on the function body at 59:8...
--> $DIR/missing-lifetimes-in-signature.rs:59:8
|
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| ^^
note: ...so that return value is valid for the call
--> $DIR/missing-lifetimes-in-signature.rs:59:45
error[E0621]: explicit lifetime required in the type of `dest`
--> $DIR/missing-lifetimes-in-signature.rs:58:45
|
LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a
| ^^^^^^^^^^^^^^^^^^^^^^^
| ------ ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required
| |
| help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T`

error[E0309]: the parameter type `G` may not live long enough
--> $DIR/missing-lifetimes-in-signature.rs:69:44
Expand All @@ -142,5 +111,5 @@ LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a

error: aborting due to 6 previous errors

Some errors have detailed explanations: E0261, E0309, E0495.
Some errors have detailed explanations: E0261, E0309, E0621.
For more information about an error, try `rustc --explain E0261`.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
error: lifetime may not live long enough
error[E0621]: explicit lifetime required in the type of `items`
--> $DIR/dyn-trait-underscore.rs:8:5
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
| - let's call the lifetime of this reference `'1`
| ---- help: add explicit lifetime `'static` to the type of `items`: `&'static [T]`
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | Box::new(items.iter())
| ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static`
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required

error: aborting due to previous error

For more information about this error, try `rustc --explain E0621`.
2 changes: 1 addition & 1 deletion src/test/ui/underscore-lifetime/dyn-trait-underscore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
// ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
Box::new(items.iter()) //~ ERROR cannot infer an appropriate lifetime
Box::new(items.iter()) //~ ERROR explicit lifetime required in the type of `items`
}

fn b<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> {
Expand Down
31 changes: 6 additions & 25 deletions src/test/ui/underscore-lifetime/dyn-trait-underscore.stderr
Original file line number Diff line number Diff line change
@@ -1,31 +1,12 @@
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> $DIR/dyn-trait-underscore.rs:8:20
|
LL | Box::new(items.iter())
| ^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the function body at 6:1...
--> $DIR/dyn-trait-underscore.rs:6:1
|
LL | / fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
LL | | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | | Box::new(items.iter())
LL | | }
| |_^
note: ...so that reference does not outlive borrowed content
--> $DIR/dyn-trait-underscore.rs:8:14
|
LL | Box::new(items.iter())
| ^^^^^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the expression is assignable
error[E0621]: explicit lifetime required in the type of `items`
--> $DIR/dyn-trait-underscore.rs:8:5
|
LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> {
| ---- help: add explicit lifetime `'static` to the type of `items`: `&'static [T]`
LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static`
LL | Box::new(items.iter())
| ^^^^^^^^^^^^^^^^^^^^^^
= note: expected `std::boxed::Box<(dyn std::iter::Iterator<Item = &T> + 'static)>`
found `std::boxed::Box<dyn std::iter::Iterator<Item = &T>>`
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required

error: aborting due to previous error

For more information about this error, try `rustc --explain E0495`.
For more information about this error, try `rustc --explain E0621`.

0 comments on commit 99d9ccd

Please sign in to comment.