Skip to content

Commit

Permalink
Account for impl Trait when suggesting lifetime
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Dec 12, 2018
1 parent dd8fc7d commit b9235ea
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 11 deletions.
31 changes: 20 additions & 11 deletions src/librustc/infer/error_reporting/mod.rs
Expand Up @@ -1095,15 +1095,16 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let sp = hir.span(id);
// `sp` only covers `T`, change it so that it covers
// `T:` when appropriate
let sp = if has_bounds {
let is_impl_trait = bound_kind.to_string().starts_with("impl ");
let sp = if has_bounds && !is_impl_trait {
sp.to(self.tcx
.sess
.source_map()
.next_point(self.tcx.sess.source_map().next_point(sp)))
} else {
sp
};
(sp, has_bounds)
(sp, has_bounds, is_impl_trait)
})
} else {
None
Expand Down Expand Up @@ -1136,25 +1137,33 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {

fn binding_suggestion<'tcx, S: fmt::Display>(
err: &mut DiagnosticBuilder<'tcx>,
type_param_span: Option<(Span, bool)>,
type_param_span: Option<(Span, bool, bool)>,
bound_kind: GenericKind<'tcx>,
sub: S,
) {
let consider = &format!(
"consider adding an explicit lifetime bound `{}: {}`...",
bound_kind, sub
let consider = format!(
"consider adding an explicit lifetime bound {}",
if type_param_span.map(|(_, _, is_impl_trait)| is_impl_trait).unwrap_or(false) {
format!(" `{}` to `{}`...", sub, bound_kind)
} else {
format!("`{}: {}`...", bound_kind, sub)
},
);
if let Some((sp, has_lifetimes)) = type_param_span {
let tail = if has_lifetimes { " + " } else { "" };
let suggestion = format!("{}: {}{}", bound_kind, sub, tail);
if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
let suggestion = if is_impl_trait {
format!("{} + {}", bound_kind, sub)
} else {
let tail = if has_lifetimes { " + " } else { "" };
format!("{}: {}{}", bound_kind, sub, tail)
};
err.span_suggestion_short_with_applicability(
sp,
consider,
&consider,
suggestion,
Applicability::MaybeIncorrect, // Issue #41966
);
} else {
err.help(consider);
err.help(&consider);
}
}

Expand Down
18 changes: 18 additions & 0 deletions src/test/ui/suggestions/suggest-impl-trait-lifetime.fixed
@@ -0,0 +1,18 @@
// run-rustfix

use std::fmt::Debug;

fn foo(d: impl Debug + 'static) {
//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug`
bar(d);
//~^ ERROR the parameter type `impl Debug` may not live long enough
//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
}

fn bar(d: impl Debug + 'static) {
println!("{:?}", d)
}

fn main() {
foo("hi");
}
18 changes: 18 additions & 0 deletions src/test/ui/suggestions/suggest-impl-trait-lifetime.rs
@@ -0,0 +1,18 @@
// run-rustfix

use std::fmt::Debug;

fn foo(d: impl Debug) {
//~^ HELP consider adding an explicit lifetime bound `'static` to `impl Debug`
bar(d);
//~^ ERROR the parameter type `impl Debug` may not live long enough
//~| NOTE ...so that the type `impl Debug` will meet its required lifetime bounds
}

fn bar(d: impl Debug + 'static) {
println!("{:?}", d)
}

fn main() {
foo("hi");
}
19 changes: 19 additions & 0 deletions src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr
@@ -0,0 +1,19 @@
error[E0310]: the parameter type `impl Debug` may not live long enough
--> $DIR/suggest-impl-trait-lifetime.rs:7:5
|
LL | bar(d);
| ^^^
|
note: ...so that the type `impl Debug` will meet its required lifetime bounds
--> $DIR/suggest-impl-trait-lifetime.rs:7:5
|
LL | bar(d);
| ^^^
help: consider adding an explicit lifetime bound `'static` to `impl Debug`...
|
LL | fn foo(d: impl Debug + 'static) {
| ^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

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

0 comments on commit b9235ea

Please sign in to comment.