1
Fork 0

Rollup merge of #90667 - rukai:improve_static_lifetime_diagnostics, r=estebank

Improve diagnostics when a static lifetime is expected

Makes progress towards https://github.com/rust-lang/rust/issues/90600

The diagnostics here were previously entirely removed due to giving a misleading suggestion but if we instead provide an informative label in that same location it should better help the user understand the situation.

I included the example from the issue as it demonstrates an area where the diagnostics are still lacking.
Happy to remove that if its just adding noise atm.
This commit is contained in:
Matthias Krüger 2021-11-17 15:57:57 +01:00 committed by GitHub
commit d7b86880d2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 269 additions and 176 deletions

View file

@ -3,8 +3,6 @@
use crate::infer::error_reporting::nice_region_error::find_anon_type::find_anon_type;
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir::intravisit::Visitor;
use rustc_hir::FnRetTy;
use rustc_middle::ty;
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
@ -48,19 +46,24 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
return None; // inapplicable
};
// Suggesting to add a `'static` lifetime to a parameter is nearly always incorrect,
// and can steer users down the wrong path.
if *named == ty::ReStatic {
return None;
}
debug!("try_report_named_anon_conflict: named = {:?}", named);
debug!("try_report_named_anon_conflict: anon_param_info = {:?}", anon_param_info);
debug!("try_report_named_anon_conflict: region_info = {:?}", region_info);
let (param, new_ty, new_ty_span, br, is_first, scope_def_id, is_impl_item) = (
anon_param_info.param,
anon_param_info.param_ty,
anon_param_info.param_ty_span,
anon_param_info.bound_region,
anon_param_info.is_first,
region_info.def_id,
region_info.is_impl_item,
);
let param = anon_param_info.param;
let new_ty = anon_param_info.param_ty;
let new_ty_span = anon_param_info.param_ty_span;
let br = anon_param_info.bound_region;
let is_first = anon_param_info.is_first;
let scope_def_id = region_info.def_id;
let is_impl_item = region_info.is_impl_item;
match br {
ty::BrAnon(_) => {}
_ => {
@ -75,26 +78,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
return None;
}
if let Some((_, fndecl)) = find_anon_type(self.tcx(), anon, &br) {
if self.is_self_anon(is_first, scope_def_id) {
return None;
}
if let FnRetTy::Return(ty) = &fndecl.output {
let mut v = ty::TraitObjectVisitor(vec![], self.tcx().hir());
v.visit_ty(ty);
debug!("try_report_named_anon_conflict: ret ty {:?}", ty);
if sub == &ty::ReStatic
&& v.0.into_iter().any(|t| t.span.desugaring_kind().is_none())
{
// If the failure is due to a `'static` requirement coming from a `dyn` or
// `impl` Trait that *isn't* caused by `async fn` desugaring, handle this case
// better in `static_impl_trait`.
debug!("try_report_named_anon_conflict: impl Trait + 'static");
return None;
}
}
if find_anon_type(self.tcx(), anon, &br).is_some()
&& self.is_self_anon(is_first, scope_def_id)
{
return None;
}
let (error_var, span_label_var) = match param.pat.simple_ident() {
@ -114,16 +101,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
);
diag.span_label(span, format!("lifetime `{}` required", named));
// Suggesting `'static` is nearly always incorrect, and can steer users
// down the wrong path.
if *named != ty::ReStatic {
diag.span_suggestion(
new_ty_span,
&format!("add explicit lifetime `{}` to {}", named, span_label_var),
new_ty.to_string(),
Applicability::Unspecified,
);
}
diag.span_suggestion(
new_ty_span,
&format!("add explicit lifetime `{}` to {}", named, span_label_var),
new_ty.to_string(),
Applicability::Unspecified,
);
Some(diag)
}

View file

@ -1,11 +1,18 @@
error[E0621]: explicit lifetime required in the type of `x`
error[E0521]: borrowed data escapes outside of function
--> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5
|
LL | fn foo(x: &()) {
| - - let's call the lifetime of this reference `'1`
| |
| `x` is a reference that is only valid in the function body
LL | / bar(|| {
LL | |
LL | | let _ = x;
LL | | })
| |______^ lifetime `'static` required
| | ^
| | |
| |______`x` escapes the function body here
| argument requires that `'1` must outlive `'static`
error[E0373]: closure may outlive the current function, but it borrows `x`, which is owned by the current function
--> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9
@ -31,5 +38,5 @@ LL | bar(move || {
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0373, E0621.
Some errors have detailed explanations: E0373, E0521.
For more information about an error, try `rustc --explain E0373`.

View file

@ -3,7 +3,7 @@ fn bar<F>(blk: F) where F: FnOnce() + 'static {
fn foo(x: &()) {
bar(|| {
//~^ ERROR explicit lifetime required in the type of `x` [E0621]
//~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
let _ = x;
})
}

View file

@ -1,9 +1,21 @@
error[E0621]: explicit lifetime required in the type of `x`
error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:9
|
LL | fn foo(x: &()) {
| --- this data with an anonymous lifetime `'_`...
LL | bar(|| {
| _________^
LL | |
LL | | let _ = x;
LL | | })
| |_____^ ...is captured here...
|
note: ...and is required to live as long as `'static` here
--> $DIR/closure-bounds-static-cant-capture-borrowed.rs:5:5
|
LL | bar(|| {
| ^^^ lifetime `'static` required
| ^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.
For more information about this error, try `rustc --explain E0759`.

View file

@ -0,0 +1,11 @@
error: lifetime may not live long enough
--> $DIR/generator-region-requirements.rs:13:51
|
LL | fn dangle(x: &mut i32) -> &'static mut i32 {
| - let's call the lifetime of this reference `'1`
...
LL | GeneratorState::Complete(c) => return c,
| ^ returning this value requires that `'1` must outlive `'static`
error: aborting due to previous error

View file

@ -6,11 +6,11 @@ fn dangle(x: &mut i32) -> &'static mut i32 {
let mut g = || {
yield;
x
//~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
};
loop {
match Pin::new(&mut g).resume(()) {
GeneratorState::Complete(c) => return c,
//~^ ERROR explicit lifetime required
GeneratorState::Yielded(_) => (),
}
}

View file

@ -1,9 +1,15 @@
error[E0621]: explicit lifetime required in the type of `x`
--> $DIR/generator-region-requirements.rs:12:51
error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/generator-region-requirements.rs:8:9
|
LL | fn dangle(x: &mut i32) -> &'static mut i32 {
| -------- this data with an anonymous lifetime `'_`...
...
LL | x
| ^ ...is captured here...
...
LL | GeneratorState::Complete(c) => return c,
| ^ lifetime `'static` required
| - ...and is required to live as long as `'static` here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.
For more information about this error, try `rustc --explain E0759`.

View file

@ -0,0 +1,26 @@
error: lifetime may not live long enough
--> $DIR/projection-type-lifetime-mismatch.rs:17:5
|
LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
| - let's call the lifetime of this reference `'1`
LL | x.m()
| ^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/projection-type-lifetime-mismatch.rs:22:5
|
LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
| - let's call the lifetime of this reference `'1`
LL | x.m()
| ^^^^^ returning this value requires that `'1` must outlive `'static`
error: lifetime may not live long enough
--> $DIR/projection-type-lifetime-mismatch.rs:27:5
|
LL | fn h(x: &()) -> &'static () {
| - let's call the lifetime of this reference `'1`
LL | x.m()
| ^^^^^ returning this value requires that `'1` must outlive `'static`
error: aborting due to 3 previous errors

View file

@ -15,17 +15,17 @@ impl X for () {
fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
x.m()
//~^ ERROR explicit lifetime required
//~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
}
fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
x.m()
//~^ ERROR explicit lifetime required
//~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
}
fn h(x: &()) -> &'static () {
x.m()
//~^ ERROR explicit lifetime required
//~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
}
fn main() {

View file

@ -1,21 +1,27 @@
error[E0621]: explicit lifetime required in the type of `x`
--> $DIR/projection-type-lifetime-mismatch.rs:17:5
error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/projection-type-lifetime-mismatch.rs:17:7
|
LL | fn f(x: &impl for<'a> X<Y<'a> = &'a ()>) -> &'static () {
| ------------------------------- this data with an anonymous lifetime `'_`...
LL | x.m()
| ^^^^^ lifetime `'static` required
| --^-- ...is captured and required to live as long as `'static` here
error[E0621]: explicit lifetime required in the type of `x`
--> $DIR/projection-type-lifetime-mismatch.rs:22:5
error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/projection-type-lifetime-mismatch.rs:22:7
|
LL | fn g<T: for<'a> X<Y<'a> = &'a ()>>(x: &T) -> &'static () {
| -- this data with an anonymous lifetime `'_`...
LL | x.m()
| ^^^^^ lifetime `'static` required
| --^-- ...is captured and required to live as long as `'static` here
error[E0621]: explicit lifetime required in the type of `x`
--> $DIR/projection-type-lifetime-mismatch.rs:27:5
error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/projection-type-lifetime-mismatch.rs:27:7
|
LL | fn h(x: &()) -> &'static () {
| --- this data with an anonymous lifetime `'_`...
LL | x.m()
| ^^^^^ lifetime `'static` required
| --^-- ...is captured and required to live as long as `'static` here
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0621`.
For more information about this error, try `rustc --explain E0759`.

View file

@ -0,0 +1,10 @@
error: lifetime may not live long enough
--> $DIR/issue-46983.rs:2:5
|
LL | fn foo(x: &u32) -> &'static u32 {
| - let's call the lifetime of this reference `'1`
LL | &*x
| ^^^ returning this value requires that `'1` must outlive `'static`
error: aborting due to previous error

View file

@ -1,6 +1,6 @@
fn foo(x: &u32) -> &'static u32 {
&*x
//~^ ERROR explicit lifetime required in the type of `x` [E0621]
//~^ ERROR `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
}
fn main() {}

View file

@ -1,9 +1,11 @@
error[E0621]: explicit lifetime required in the type of `x`
error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/issue-46983.rs:2:5
|
LL | fn foo(x: &u32) -> &'static u32 {
| ---- this data with an anonymous lifetime `'_`...
LL | &*x
| ^^^ lifetime `'static` required
| ^^^ ...is captured and required to live as long as `'static` here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.
For more information about this error, try `rustc --explain E0759`.

View file

@ -0,0 +1,24 @@
error[E0597]: `foo` does not live long enough
--> $DIR/issue-90600-expected-return-static-indirect.rs:7:32
|
LL | let refcell = RefCell::new(&mut foo);
| ^^^^^^^^ borrowed value does not live long enough
LL |
LL | let read = &refcell as &RefCell<dyn Read>;
| -------- cast requires that `foo` is borrowed for `'static`
...
LL | }
| - `foo` dropped here while still borrowed
error: lifetime may not live long enough
--> $DIR/issue-90600-expected-return-static-indirect.rs:9:16
|
LL | fn inner(mut foo: &[u8]) {
| - let's call the lifetime of this reference `'1`
...
LL | let read = &refcell as &RefCell<dyn Read>;
| ^^^^^^^^ cast requires that `'1` must outlive `'static`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0597`.

View file

@ -0,0 +1,14 @@
use std::cell::RefCell;
use std::io::Read;
fn main() {}
fn inner(mut foo: &[u8]) {
let refcell = RefCell::new(&mut foo);
//~^ ERROR `foo` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
let read = &refcell as &RefCell<dyn Read>;
read_thing(read);
}
fn read_thing(refcell: &RefCell<dyn Read>) {}

View file

@ -0,0 +1,14 @@
error[E0759]: `foo` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/issue-90600-expected-return-static-indirect.rs:7:32
|
LL | fn inner(mut foo: &[u8]) {
| ----- this data with an anonymous lifetime `'_`...
LL | let refcell = RefCell::new(&mut foo);
| ^^^^^^^^ ...is captured here...
...
LL | read_thing(read);
| ---- ...and is required to live as long as `'static` here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0759`.

View file

@ -7,7 +7,7 @@
fn foo(x: &u32) -> &'static u32 {
&*x
//~^ ERROR explicit lifetime required in the type of `x`
//~^ ERROR lifetime may not live long enough
}
fn main() { }

View file

@ -1,9 +1,10 @@
error[E0621]: explicit lifetime required in the type of `x`
error: lifetime may not live long enough
--> $DIR/region-lbr-anon-does-not-outlive-static.rs:9:5
|
LL | fn foo(x: &u32) -> &'static u32 {
| - let's call the lifetime of this reference `'1`
LL | &*x
| ^^^ lifetime `ReStatic` required
| ^^^ returning this value requires that `'1` must outlive `'static`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0621`.

View file

@ -12,7 +12,7 @@ fn foo(s: &mut (i32,)) -> i32 {
fn bar(s: &Box<(i32,)>) -> &'static i32 {
// FIXME(#46983): error message should be better
&s.0 //~ ERROR explicit lifetime required in the type of `s` [E0621]
&s.0 //~ ERROR lifetime may not live long enough
}
fn main() {

View file

@ -9,13 +9,15 @@ LL | *s = (2,);
LL | *x
| -- borrow later used here
error[E0621]: explicit lifetime required in the type of `s`
error: lifetime may not live long enough
--> $DIR/guarantor-issue-46974.rs:15:5
|
LL | fn bar(s: &Box<(i32,)>) -> &'static i32 {
| - let's call the lifetime of this reference `'1`
LL | // FIXME(#46983): error message should be better
LL | &s.0
| ^^^^ lifetime `'static` required
| ^^^^ returning this value requires that `'1` must outlive `'static`
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0506, E0621.
For more information about an error, try `rustc --explain E0506`.
For more information about this error, try `rustc --explain E0506`.

View file

@ -1,28 +0,0 @@
error: lifetime may not live long enough
--> $DIR/regions-static-bound.rs:9:5
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
| -- lifetime `'a` defined here
LL | t //[ll]~ ERROR E0312
| ^ returning this value requires that `'a` must outlive `'static`
error[E0621]: explicit lifetime required in the type of `u`
--> $DIR/regions-static-bound.rs:14:5
|
LL | fn error(u: &(), v: &()) {
| --- help: add explicit lifetime `'static` to the type of `u`: `&'static ()`
LL | static_id(&u); //[ll]~ ERROR explicit lifetime required in the type of `u` [E0621]
| ^^^^^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/regions-static-bound.rs:16:5
|
LL | fn error(u: &(), v: &()) {
| --- help: add explicit lifetime `'static` to the type of `v`: `&'static ()`
...
LL | static_id_indirect(&v); //[ll]~ ERROR explicit lifetime required in the type of `v` [E0621]
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0621`.

View file

@ -1,23 +0,0 @@
error: lifetime may not live long enough
--> $DIR/regions-static-bound.rs:9:5
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
| -- lifetime `'a` defined here
LL | t
| ^ returning this value requires that `'a` must outlive `'static`
error[E0621]: explicit lifetime required in the type of `u`
--> $DIR/regions-static-bound.rs:14:5
|
LL | static_id(&u);
| ^^^^^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/regions-static-bound.rs:16:5
|
LL | static_id_indirect(&v);
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0621`.

View file

@ -1,29 +0,0 @@
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> $DIR/regions-static-bound.rs:9:5
|
LL | t
| ^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime `'a` as defined here
--> $DIR/regions-static-bound.rs:8:24
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
| ^^
error[E0621]: explicit lifetime required in the type of `u`
--> $DIR/regions-static-bound.rs:14:5
|
LL | static_id(&u);
| ^^^^^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/regions-static-bound.rs:16:5
|
LL | static_id_indirect(&v);
| ^^^^^^^^^^^^^^^^^^ lifetime `'static` required
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0312, E0621.
For more information about an error, try `rustc --explain E0312`.

View file

@ -1,23 +1,38 @@
error: lifetime may not live long enough
--> $DIR/regions-static-bound.rs:9:5
--> $DIR/regions-static-bound.rs:6:5
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
| -- lifetime `'a` defined here
LL | t
| ^ returning this value requires that `'a` must outlive `'static`
error[E0621]: explicit lifetime required in the type of `u`
--> $DIR/regions-static-bound.rs:14:5
error[E0521]: borrowed data escapes outside of function
--> $DIR/regions-static-bound.rs:10:5
|
LL | fn error(u: &(), v: &()) {
| - - let's call the lifetime of this reference `'1`
| |
| `u` is a reference that is only valid in the function body
LL | static_id(&u);
| ^^^^^^^^^^^^^ lifetime `'static` required
| ^^^^^^^^^^^^^
| |
| `u` escapes the function body here
| argument requires that `'1` must outlive `'static`
error[E0621]: explicit lifetime required in the type of `v`
--> $DIR/regions-static-bound.rs:16:5
error[E0521]: borrowed data escapes outside of function
--> $DIR/regions-static-bound.rs:11:5
|
LL | fn error(u: &(), v: &()) {
| - - let's call the lifetime of this reference `'2`
| |
| `v` is a reference that is only valid in the function body
LL | static_id(&u);
LL | static_id_indirect(&v);
| ^^^^^^^^^^^^^^^^^^^^^^ lifetime `'static` required
| ^^^^^^^^^^^^^^^^^^^^^^
| |
| `v` escapes the function body here
| argument requires that `'2` must outlive `'static`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0621`.
For more information about this error, try `rustc --explain E0521`.

View file

@ -1,20 +1,14 @@
// revisions: migrate nll
//[nll] compile-flags:-Zborrowck=mir
fn static_id<'a,'b>(t: &'a ()) -> &'static ()
where 'a: 'static { t }
fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
where 'a: 'b, 'b: 'static { t }
fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
t //[migrate]~ ERROR E0312
//[nll]~^ ERROR lifetime may not live long enough
t //~ ERROR E0312
}
fn error(u: &(), v: &()) {
static_id(&u); //[migrate]~ ERROR explicit lifetime required in the type of `u` [E0621]
//[nll]~^ ERROR explicit lifetime required in the type of `u` [E0621]
static_id_indirect(&v); //[migrate]~ ERROR explicit lifetime required in the type of `v` [E0621]
//[nll]~^ ERROR explicit lifetime required in the type of `v` [E0621]
static_id(&u); //~ ERROR `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
static_id_indirect(&v); //~ ERROR `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759]
}
fn main() {}

View file

@ -0,0 +1,46 @@
error[E0312]: lifetime of reference outlives lifetime of borrowed content...
--> $DIR/regions-static-bound.rs:6:5
|
LL | t
| ^
|
= note: ...the reference is valid for the static lifetime...
note: ...but the borrowed content is only valid for the lifetime `'a` as defined here
--> $DIR/regions-static-bound.rs:5:24
|
LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
| ^^
error[E0759]: `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/regions-static-bound.rs:10:5
|
LL | fn error(u: &(), v: &()) {
| --- this data with an anonymous lifetime `'_`...
LL | static_id(&u);
| ^^^^^^^^^ -- ...is captured here...
|
note: ...and is required to live as long as `'static` here
--> $DIR/regions-static-bound.rs:10:5
|
LL | static_id(&u);
| ^^^^^^^^^
error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
--> $DIR/regions-static-bound.rs:11:5
|
LL | fn error(u: &(), v: &()) {
| --- this data with an anonymous lifetime `'_`...
LL | static_id(&u);
LL | static_id_indirect(&v);
| ^^^^^^^^^^^^^^^^^^ -- ...is captured here...
|
note: ...and is required to live as long as `'static` here
--> $DIR/regions-static-bound.rs:11:5
|
LL | static_id_indirect(&v);
| ^^^^^^^^^^^^^^^^^^
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0312, E0759.
For more information about an error, try `rustc --explain E0312`.