1
Fork 0

Rollup merge of #56755 - estebank:impl-trait-lt-sugg, r=cramertj

Account for `impl Trait` when suggesting lifetime

Fix https://github.com/rust-lang/rust/issues/56745
This commit is contained in:
Pietro Albini 2018-12-15 10:17:36 +01:00 committed by GitHub
commit c530e31245
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 75 additions and 11 deletions

View file

@ -1095,7 +1095,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let sp = hir.span(id); let sp = hir.span(id);
// `sp` only covers `T`, change it so that it covers // `sp` only covers `T`, change it so that it covers
// `T:` when appropriate // `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 sp.to(self.tcx
.sess .sess
.source_map() .source_map()
@ -1103,7 +1104,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
} else { } else {
sp sp
}; };
(sp, has_bounds) (sp, has_bounds, is_impl_trait)
}) })
} else { } else {
None None
@ -1136,25 +1137,33 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn binding_suggestion<'tcx, S: fmt::Display>( fn binding_suggestion<'tcx, S: fmt::Display>(
err: &mut DiagnosticBuilder<'tcx>, err: &mut DiagnosticBuilder<'tcx>,
type_param_span: Option<(Span, bool)>, type_param_span: Option<(Span, bool, bool)>,
bound_kind: GenericKind<'tcx>, bound_kind: GenericKind<'tcx>,
sub: S, sub: S,
) { ) {
let consider = &format!( let consider = format!(
"consider adding an explicit lifetime bound `{}: {}`...", "consider adding an explicit lifetime bound {}",
bound_kind, sub 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 { if let Some((sp, has_lifetimes, is_impl_trait)) = type_param_span {
let tail = if has_lifetimes { " + " } else { "" }; let suggestion = if is_impl_trait {
let suggestion = format!("{}: {}{}", bound_kind, sub, tail); format!("{} + {}", bound_kind, sub)
} else {
let tail = if has_lifetimes { " + " } else { "" };
format!("{}: {}{}", bound_kind, sub, tail)
};
err.span_suggestion_short_with_applicability( err.span_suggestion_short_with_applicability(
sp, sp,
consider, &consider,
suggestion, suggestion,
Applicability::MaybeIncorrect, // Issue #41966 Applicability::MaybeIncorrect, // Issue #41966
); );
} else { } else {
err.help(consider); err.help(&consider);
} }
} }

View file

@ -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");
}

View file

@ -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");
}

View file

@ -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`.